diff options
| author | Ben Culkin <scorpress@gmail.com> | 2020-12-29 18:30:32 -0500 |
|---|---|---|
| committer | Ben Culkin <scorpress@gmail.com> | 2020-12-29 18:33:58 -0500 |
| commit | bd1bafc799a75a75b60c5376d55a5bc028e85072 (patch) | |
| tree | a6d15650e87a56a40ca88dcd75e3cddb5ec504a2 | |
| parent | 4808d411b3b6e4e237f7a7c336c751419e763d2b (diff) | |
Implement 'effect groups' as an explicit concept
| -rw-r--r-- | src/main/java/tlIItools/Affix.java | 22 | ||||
| -rw-r--r-- | src/main/java/tlIItools/Effect.java | 310 | ||||
| -rw-r--r-- | src/main/java/tlIItools/EffectGroup.java | 74 |
3 files changed, 179 insertions, 227 deletions
diff --git a/src/main/java/tlIItools/Affix.java b/src/main/java/tlIItools/Affix.java index b147ab0b..00fff77a 100644 --- a/src/main/java/tlIItools/Affix.java +++ b/src/main/java/tlIItools/Affix.java @@ -88,10 +88,18 @@ public class Affix { if (effects == null) { if (afx.effects != null) return false; } else if (!effects.equals(afx.effects)) { - // TODO this isn't actually an equals; maybe make this a 'isEquivalent' or 'isSimilarEffect'? - // -bculkin, 12/29/2020 - return false; - } else if (enchantSources == null) { + Iterator<Effect> leftIter = effects.iterator(); + Iterator<Effect> rightIter = afx.effects.iterator(); + + while (leftIter.hasNext() && rightIter.hasNext()) { + Effect left = leftIter.next(); + Effect right = rightIter.next(); + + if (!left.group.equals(right.group)) return false; + } + } + + if (enchantSources == null) { if (afx.enchantSources != null) return false; } else if (!enchantSources.equals(afx.enchantSources)) { return false; @@ -133,14 +141,10 @@ public class Affix { public String getAffixGroupName() { StringBuilder sb = new StringBuilder(); - for (Effect eft : effects) sb.append(eft.getEffectGroup()); - + for (Effect eft : effects) sb.append(eft.group); for (String enchantSource : enchantSources) sb.append(enchantSource); - for (String equipType : equipTypes) sb.append(equipType); - for (String nonEquipType : nonequipTypes) sb.append(nonEquipType); - for (String socketableType : socketableTypes) sb.append(socketableType); return sb.toString(); diff --git a/src/main/java/tlIItools/Effect.java b/src/main/java/tlIItools/Effect.java index b6b7e30f..fd7867d0 100644 --- a/src/main/java/tlIItools/Effect.java +++ b/src/main/java/tlIItools/Effect.java @@ -13,54 +13,31 @@ public class Effect { /** The file name this effect came from. */ public String fName; - /** The name of the effect. */ - public String name; - - /** The specific effect that happens. */ - public String type; - - /** Damage type for the effect, if applicable. */ - public String damageType = "physical"; - /** Duration of the effect. */ public double duration; - /** Whether or not we have a duration or not. */ - public boolean hasDuration; - /** Minimum value for the effect. */ public double minValue; /** Maximum value for the effect. */ public double maxValue; - /** The name of the stat that applies to this affect. */ - public String statName; /** The percent of the stat value to apply. */ public double statPercent; - /** Whether or not this stat is a bonus value. */ - public boolean isStatBonus; - - /** Whether or not this uses the owners level to modify any applicable graph. */ - public boolean ownerLevel; - - /** Whether or not a graph is used for this effect. */ - public boolean useGraph = true; - /** The graph to use instead of the default graph. */ - public String graphOverride; - - /** Whether this effect can stack with itself. */ - public boolean exclusive; - /** The amount the targets armor is reduced by for this effect. */ public double soakScale = 1.0; /** Level of the effect. */ public int level = -1; - /** Whether or not this effect is a 'transfer' effect (Applied to the enemy on a hit). */ - public boolean isTransfer; - - /** The amount to resist/do knockback by. */ + /** The 'effect group' this effect belongs to. + * + * An 'effect group is essentially any other effect that is the same general sort of effect, just with different details. + * + * For instance, an effect that grants +4 strength would group with one granting +8 strength, + * assuming that most other details were equal. */ + public EffectGroup group = new EffectGroup(); + + /** The amount to resist/do knockback by. */ public double resist; /** Minimum value per monster. */ @@ -82,57 +59,31 @@ public class Effect { public Effect() { } - - /** Gets the 'effect group' this effect belongs to. - * - * An 'effect group is essentially any other effect that is the same general sort of effect, just with different details. - * - * For instance, an effect that grants +4 strength would group with one granting +8 strength, - * assuming that most other details were equal. - * - * @return The 'effect group' this effect belongs to. */ - public String getEffectGroup() { - StringBuilder sb = new StringBuilder(); - - sb.append(name); - sb.append(type); - sb.append(damageType); - sb.append(hasDuration); - sb.append(statName); - sb.append(isStatBonus); - sb.append(ownerLevel); - sb.append(graphOverride); - sb.append(useGraph); - sb.append(exclusive); - sb.append(isTransfer); - - return sb.toString(); - } @Override public String toString() { StringBuilder sb = new StringBuilder(); - if (isTransfer) { + if (group.isTransfer) { sb.append("Inflict on Hit: "); } - Map<String, String> detMap = hasDuration ? EffectRepo.timeDetals : EffectRepo.detals; + Map<String, String> detMap = group.hasDuration ? EffectRepo.timeDetals : EffectRepo.detals; - if (detMap.containsKey(type) || - (hasDuration - && !EffectRepo.timeDetals.containsKey(type) - && EffectRepo.detals.containsKey(type))) + if (detMap.containsKey(group.type) || + (group.hasDuration + && !EffectRepo.timeDetals.containsKey(group.type) + && EffectRepo.detals.containsKey(group.type))) { String fmt; - if (hasDuration - && !EffectRepo.timeDetals.containsKey(type) - && EffectRepo.detals.containsKey(type)) + if (group.hasDuration + && !EffectRepo.timeDetals.containsKey(group.type) + && EffectRepo.detals.containsKey(group.type)) { - AffixLister.errOut.printf("Improvised details for timed %s\n", type); - fmt = EffectRepo.detals.get(type) + "for <DUR> seconds"; + AffixLister.errOut.printf("Improvised details for timed %s\n", group.type); + fmt = EffectRepo.detals.get(group.type) + "for <DUR> seconds"; } else { - fmt = detMap.get(type); + fmt = detMap.get(group.type); } // Expand aliases first. @@ -145,44 +96,44 @@ public class Effect { if (minPer >= 0 && maxPer >= 0) { fmt = fmt.replaceAll("<MC\\|([^|>]+)\\|([^|>]+)>", "$2"); } if (fmt.contains("<") || fmt.contains(">")) { - AffixLister.errOut.printf("WARN: Details for effect %s are malformatted (contains < or >):\n\t%s\n", type, fmt); + AffixLister.errOut.printf("WARN: Details for effect %s are malformatted (contains < or >):\n\t%s\n", group.type, fmt); } sb.append(String.format(fmt, Math.abs(minValue), Math.abs(maxValue), - duration, damageType.toLowerCase(), level, resist, name, + duration, group.damageType.toLowerCase(), level, resist, group.name, Math.abs(minPer), Math.abs(maxPer), range, maxCount, pulse)); } else { sb.append("No effect details for effect "); - sb.append(type); + sb.append(group.type); sb.append(String.format( " with parameters (min %.2f, max %.2f, dur %.2f, type %s, level %d)", - minValue, maxValue, duration, damageType.toLowerCase(), level, name)); + minValue, maxValue, duration, group.damageType.toLowerCase(), level, group.name)); if (AffixLister.addFileName) { sb.append(" from file "); sb.append(fName); } - if (hasDuration) AffixLister.errOut.print("TIMED: "); + if (group.hasDuration) AffixLister.errOut.print("TIMED: "); AffixLister.errOut.println(sb.toString()); } - if (name != null) { + if (group.name != null) { sb.append(" (named "); - sb.append(name); + sb.append(group.name); sb.append(")"); } - if (exclusive) sb.append(" (Exclusive)"); + if (group.exclusive) sb.append(" (Exclusive)"); - if (graphOverride != null) { + if (group.graphOverride != null) { sb.append(" (Uses "); - sb.append(graphOverride); + sb.append(group.graphOverride); sb.append(" graph)"); } - if (ownerLevel) { + if (group.ownerLevel) { sb.append(" (Uses owner level for graph)"); } @@ -198,135 +149,58 @@ public class Effect { sb.append(")"); } - if (statName != null) { - sb.append(String.format(" (%.2f of stat %s", statPercent, statName)); + if (group.statName != null) { + sb.append(String.format(" (%.2f of stat %s", statPercent, group.statName)); - if (isStatBonus) sb.append(" as bonus)"); + if (group.isStatBonus) sb.append(" as bonus)"); else sb.append(")"); } - if (!useGraph) sb.append(" (Ignoring graph)"); + if (!group.useGraph) sb.append(" (Ignoring graph)"); return sb.toString(); } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((damageType == null) ? 0 : damageType.hashCode()); - long temp; - temp = Double.doubleToLongBits(duration); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + (exclusive ? 1231 : 1237); - result = prime * result - + ((graphOverride == null) ? 0 : graphOverride.hashCode()); - result = prime * result + (hasDuration ? 1231 : 1237); - result = prime * result + (isStatBonus ? 1231 : 1237); - result = prime * result + (isTransfer ? 1231 : 1237); - result = prime * result + level; - temp = Double.doubleToLongBits(maxCount); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(maxPer); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(maxValue); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(minPer); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(minValue); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + (ownerLevel ? 1231 : 1237); - temp = Double.doubleToLongBits(pulse); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(range); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(resist); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(soakScale); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + ((statName == null) ? 0 : statName.hashCode()); - temp = Double.doubleToLongBits(statPercent); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result + (useGraph ? 1231 : 1237); - return result; - } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - Effect other = (Effect) obj; - - if (damageType == null) { - if (other.damageType != null) return false; - } else if (!damageType.equals(other.damageType)) - return false; - if (Double.doubleToLongBits(duration) != Double.doubleToLongBits(other.duration)) - return false; - if (exclusive != other.exclusive) - return false; - if (graphOverride == null) { - if (other.graphOverride != null) - return false; - } else if (!graphOverride.equals(other.graphOverride)) - return false; - if (hasDuration != other.hasDuration) - return false; - if (isStatBonus != other.isStatBonus) - return false; - if (isTransfer != other.isTransfer) - return false; - if (level != other.level) - return false; - if (Double.doubleToLongBits(maxCount) != Double.doubleToLongBits(other.maxCount)) - return false; - if (Double.doubleToLongBits(maxPer) != Double.doubleToLongBits(other.maxPer)) - return false; - if (Double.doubleToLongBits(maxValue) != Double.doubleToLongBits(other.maxValue)) - return false; - if (Double.doubleToLongBits(minPer) != Double.doubleToLongBits(other.minPer)) - return false; - if (Double.doubleToLongBits(minValue) != Double.doubleToLongBits(other.minValue)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (ownerLevel != other.ownerLevel) - return false; - if (Double.doubleToLongBits(pulse) != Double.doubleToLongBits(other.pulse)) - return false; - if (Double.doubleToLongBits(range) != Double.doubleToLongBits(other.range)) - return false; - if (Double.doubleToLongBits(resist) != Double.doubleToLongBits(other.resist)) - return false; - if (Double.doubleToLongBits(soakScale) - != Double.doubleToLongBits(other.soakScale)) - return false; - if (statName == null) { - if (other.statName != null) - return false; - } else if (!statName.equals(other.statName)) - return false; - if (Double.doubleToLongBits(statPercent) - != Double.doubleToLongBits(other.statPercent)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (useGraph != other.useGraph) - return false; - return true; - } - - /** Parse an effect. + public int hashCode() { + return Objects.hash(duration, fName, group, level, maxCount, maxPer, maxValue, + minPer, minValue, pulse, range, resist, soakScale, statPercent); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Effect other = (Effect) obj; + return Double.doubleToLongBits(duration) + == Double.doubleToLongBits(other.duration) + && Objects.equals(fName, other.fName) + && Objects.equals(group, other.group) && level == other.level + && Double.doubleToLongBits(maxCount) + == Double.doubleToLongBits(other.maxCount) + && Double.doubleToLongBits(maxPer) + == Double.doubleToLongBits(other.maxPer) + && Double.doubleToLongBits(maxValue) + == Double.doubleToLongBits(other.maxValue) + && Double.doubleToLongBits(minPer) + == Double.doubleToLongBits(other.minPer) + && Double.doubleToLongBits(minValue) + == Double.doubleToLongBits(other.minValue) + && Double.doubleToLongBits(pulse) == Double.doubleToLongBits(other.pulse) + && Double.doubleToLongBits(range) == Double.doubleToLongBits(other.range) + && Double.doubleToLongBits(resist) + == Double.doubleToLongBits(other.resist) + && Double.doubleToLongBits(soakScale) + == Double.doubleToLongBits(other.soakScale) + && Double.doubleToLongBits(statPercent) + == Double.doubleToLongBits(other.statPercent); + } + + /** Parse an effect. * * @param afx The affix the effect belongs to. * @param scn The scanner to read from. @@ -365,11 +239,11 @@ public class Effect { if (splits.length == 1) continue; if (ln.contains("NAME")) { - efct.name = splits[1]; + efct.group.name = splits[1]; } else if (ln.contains("DAMAGE_TYPE")) { - efct.damageType = splits[1]; + efct.group.damageType = splits[1]; } else if (ln.contains("TYPE")) { - efct.type = splits[1]; + efct.group.type = splits[1]; } else if (ln.contains("ACTIVATION")) { switch (splits[1]) { case "DYNAMIC": @@ -379,31 +253,31 @@ public class Effect { // actual difference. break; case "TRANSFER": - efct.isTransfer = true; + efct.group.isTransfer = true; break; default: - errs.add(String.format("Malformed activation type: (%s) (%s) (%s)\n", splits[1], efct.name, afx.intName)); + errs.add(String.format("Malformed activation type: (%s) (%s) (%s)\n", splits[1], efct.group.name, afx.intName)); } } else if (ln.contains("DURATION")) { if (splits[1].equals("ALWAYS")) { - efct.hasDuration = false; + efct.group.hasDuration = false; efct.duration = Double.POSITIVE_INFINITY; } else if (splits[1].equals("INSTANT")) { - efct.hasDuration = false; + efct.group.hasDuration = false; efct.duration = Double.NaN; } else if (splits[1].equals("PERCENT")) { - efct.hasDuration = false; + efct.group.hasDuration = false; efct.duration = Double.NaN; errs.add(String.format("WARN: Punting on DURATION:PERCENT for %s\n", scnSource)); } else if (splits[1].equals("0")) { - efct.hasDuration = false; + efct.group.hasDuration = false; efct.duration = 0.0; } else { - efct.hasDuration = true; + efct.group.hasDuration = true; if (splits[1].equalsIgnoreCase("instant")) { efct.duration = -1; @@ -420,19 +294,19 @@ public class Effect { } else if (ln.contains("LEVEL:")) { efct.level = Integer.parseInt(splits[1]); } else if (ln.contains("EXCLUSIVE")) { - efct.exclusive = Boolean.parseBoolean(splits[1]); + efct.group.exclusive = Boolean.parseBoolean(splits[1]); } else if (ln.contains("GRAPHOVERRIDE")) { - efct.graphOverride = splits[1]; + efct.group.graphOverride = splits[1]; } else if (ln.contains("USEOWNERLEVEL")) { - efct.ownerLevel = Boolean.parseBoolean(splits[1]); + efct.group.ownerLevel = Boolean.parseBoolean(splits[1]); } else if (ln.contains("NOGRAPH")) { - efct.useGraph = Boolean.parseBoolean(splits[1]); + efct.group.useGraph = Boolean.parseBoolean(splits[1]); } else if (ln.contains("STATNAME")) { - efct.statName = splits[1]; + efct.group.statName = splits[1]; } else if (ln.contains("STATPERCENT")) { efct.statPercent = Double.parseDouble(splits[1]); } else if (ln.contains("STATMODIFIERISBONUS")) { - efct.isStatBonus = Boolean.parseBoolean(splits[1]); + efct.group.isStatBonus = Boolean.parseBoolean(splits[1]); } else if (ln.contains("RESISTANCE:")) { efct.resist = Double.parseDouble(splits[1]); } else if (ln.contains("FORCE:")) { @@ -458,7 +332,7 @@ public class Effect { String fmt = "\t\tProcessed effect %s from %s in %d nanoseconds (%.2f seconds)\n"; double seconds = (((endTime - startTime) / 1000000000)); - errs.add(String.format(fmt, efct.name, scnSource, endTime - startTime, seconds)); + errs.add(String.format(fmt, efct.group.name, scnSource, endTime - startTime, seconds)); } effectCount += 1; diff --git a/src/main/java/tlIItools/EffectGroup.java b/src/main/java/tlIItools/EffectGroup.java new file mode 100644 index 00000000..29e51d25 --- /dev/null +++ b/src/main/java/tlIItools/EffectGroup.java @@ -0,0 +1,74 @@ +package tlIItools; + +import java.util.*; + +public class EffectGroup { + /** The name of the effect. */ + public String name; + /** The specific effect that happens. */ + public String type; + /** Damage type for the effect, if applicable. */ + public String damageType = "physical"; + /** Whether or not we have a duration or not. */ + public boolean hasDuration; + /** The name of the stat that applies to this affect. */ + public String statName; + /** Whether or not this stat is a bonus value. */ + public boolean isStatBonus; + /** Whether or not this uses the owners level to modify any applicable graph. */ + public boolean ownerLevel; + /** Whether or not a graph is used for this effect. */ + public boolean useGraph = true; + /** The graph to use instead of the default graph. */ + public String graphOverride; + /** Whether this effect can stack with itself. */ + public boolean exclusive; + /** Whether or not this effect is a 'transfer' effect (Applied to the enemy on a hit). */ + public boolean isTransfer; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append(name); + sb.append(type); + sb.append(damageType); + sb.append(hasDuration); + sb.append(statName); + sb.append(isStatBonus); + sb.append(ownerLevel); + sb.append(graphOverride); + sb.append(useGraph); + sb.append(exclusive); + sb.append(isTransfer); + + return sb.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(damageType, exclusive, graphOverride, hasDuration, + isStatBonus, isTransfer, name, ownerLevel, statName, type, useGraph); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + EffectGroup other = (EffectGroup) obj; + + return Objects.equals(damageType, other.damageType) + && Objects.equals(graphOverride, other.graphOverride) + && Objects.equals(name, other.name) + && Objects.equals(statName, other.statName) + && Objects.equals(type, other.type) + && exclusive == other.exclusive + && hasDuration == other.hasDuration + && isStatBonus == other.isStatBonus + && isTransfer == other.isTransfer + && ownerLevel == other.ownerLevel + && useGraph == other.useGraph; + } +}
\ No newline at end of file |
