This repository has been archived by the owner on Jul 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 72
/
ControlPointParser.java
116 lines (100 loc) · 6.71 KB
/
ControlPointParser.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package tc.oc.pgm.controlpoint;
import java.time.Duration;
import java.util.stream.Stream;
import javax.inject.Inject;
import com.google.common.collect.Range;
import org.bukkit.Material;
import org.bukkit.util.Vector;
import org.jdom2.Element;
import tc.oc.pgm.features.FeatureDefinitionParser;
import tc.oc.pgm.features.FeatureParser;
import tc.oc.pgm.filters.Filter;
import tc.oc.pgm.filters.matcher.block.MaterialFilter;
import tc.oc.pgm.filters.operator.AnyFilter;
import tc.oc.pgm.filters.parser.FilterParser;
import tc.oc.pgm.regions.BlockBoundedValidation;
import tc.oc.pgm.regions.Region;
import tc.oc.pgm.regions.RegionParser;
import tc.oc.pgm.teams.TeamFactory;
import tc.oc.pgm.utils.MaterialPattern;
import tc.oc.pgm.utils.XMLUtils;
import tc.oc.pgm.xml.InvalidXMLException;
import tc.oc.pgm.xml.Node;
public final class ControlPointParser implements FeatureDefinitionParser<ControlPointDefinition> {
private static final Filter VISUAL_MATERIALS = AnyFilter.of(Stream.of(Material.WOOL,
Material.CARPET,
Material.STAINED_CLAY,
Material.STAINED_GLASS,
Material.STAINED_GLASS_PANE)
.map(material -> MaterialFilter.of(MaterialPattern.accepting(material))));
private final RegionParser regionParser;
private final FilterParser filterParser;
private final FeatureParser<TeamFactory> teamParser;
@Inject private ControlPointParser(RegionParser regionParser, FilterParser filterParser, FeatureParser<TeamFactory> teamParser) {
this.regionParser = regionParser;
this.filterParser = filterParser;
this.teamParser = teamParser;
}
@Override
public ControlPointDefinition parseElement(Element elControlPoint) throws InvalidXMLException {
final boolean koth = "hill".equals(elControlPoint.getName());
Region captureRegion = regionParser.property(elControlPoint, "capture-region")
.alias("capture")
.union();
Region progressDisplayRegion = regionParser.property(elControlPoint, "progress-display-region")
.alias("progress-display", "progress")
.validate(BlockBoundedValidation.INSTANCE)
.optionalUnion(null);
Region ownerDisplayRegion = regionParser.property(elControlPoint, "owner-display-region")
.alias("owner-display", "captured")
.validate(BlockBoundedValidation.INSTANCE)
.optionalUnion(null);
Filter captureFilter = filterParser.property(elControlPoint, "capture-filter").optional(null);
Filter playerFilter = filterParser.property(elControlPoint, "player-filter").optional(null);
Filter visualMaterials = filterParser.property(elControlPoint, "visual-materials")
.optionalMulti()
.<Filter>map(AnyFilter::new)
.orElse(VISUAL_MATERIALS);
String name = elControlPoint.getAttributeValue("name", "Hill");
TeamFactory initialOwner = teamParser.property(elControlPoint, "initial-owner").optional(null);
Vector capturableDisplayBeacon = XMLUtils.parseVector(elControlPoint.getAttribute("beacon"));
Duration timeToCapture = XMLUtils.parseDuration(elControlPoint.getAttribute("capture-time"), Duration.ofSeconds(30));
double timeMultiplier = XMLUtils.parseNumber(elControlPoint.getAttribute("time-multiplier"), Double.class, koth ? 0.1D : 0D);
final double recoveryRate, decayRate;
final Node attrIncremental = Node.fromAttr(elControlPoint, "incremental");
final Node attrRecovery = Node.fromAttr(elControlPoint, "recovery");
final Node attrDecay = Node.fromAttr(elControlPoint, "decay");
if(attrIncremental == null) {
recoveryRate = XMLUtils.parseNumber(attrRecovery, Double.class, Range.atLeast(0D), koth ? 1D : Double.POSITIVE_INFINITY);
decayRate = XMLUtils.parseNumber(attrDecay, Double.class, Range.atLeast(0D), koth ? 0D : Double.POSITIVE_INFINITY);
} else {
if(attrRecovery != null || attrDecay != null) {
throw new InvalidXMLException("Cannot combine this attribute with 'incremental'", attrRecovery != null ? attrRecovery : attrDecay);
}
final boolean incremental = XMLUtils.parseBoolean(attrIncremental, koth);
recoveryRate = incremental ? 1D : Double.POSITIVE_INFINITY;
decayRate = incremental ? 0D : Double.POSITIVE_INFINITY;
}
boolean neutralState = XMLUtils.parseBoolean(elControlPoint.getAttribute("neutral-state"), koth);
boolean permanent = XMLUtils.parseBoolean(elControlPoint.getAttribute("permanent"), false);
float pointsOwned = XMLUtils.parseNumber(elControlPoint.getAttribute("owner-points"), Float.class, 0f);
float pointsPerSecond = XMLUtils.parseNumber(elControlPoint.getAttribute("points"), Float.class, 1f);
float pointsGrowth = XMLUtils.parseNumber(elControlPoint.getAttribute("points-growth"), Float.class, Float.POSITIVE_INFINITY);
boolean showProgress = XMLUtils.parseBoolean(elControlPoint.getAttribute("show-progress"), koth);
boolean visible = XMLUtils.parseBoolean(elControlPoint.getAttribute("show"), true);
Boolean required = XMLUtils.parseBoolean(elControlPoint.getAttribute("required"), null);
ControlPointDefinition.CaptureCondition captureCondition =
XMLUtils.parseEnum(Node.fromAttr(elControlPoint, "capture-rule"),
ControlPointDefinition.CaptureCondition.class,
"capture rule",
ControlPointDefinition.CaptureCondition.EXCLUSIVE);
return new ControlPointDefinitionImpl(
name, required, visible,
captureRegion, captureFilter, playerFilter,
progressDisplayRegion, ownerDisplayRegion, visualMaterials,
capturableDisplayBeacon == null ? null : capturableDisplayBeacon.toBlockVector(),
timeToCapture, timeMultiplier, recoveryRate, decayRate, initialOwner, captureCondition,
neutralState, permanent, pointsOwned, pointsPerSecond, pointsGrowth, showProgress
);
}
}