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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
package shcm.shsupercm.fabric.citresewn.cit.builtin.conditions;
import shcm.shsupercm.fabric.citresewn.cit.CITCondition;
import shcm.shsupercm.fabric.citresewn.cit.CITContext;
import shcm.shsupercm.fabric.citresewn.cit.CITParsingException;
import shcm.shsupercm.fabric.citresewn.pack.format.PropertyGroup;
import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue;
import static java.lang.Float.*;
/**
* Common condition parser for floats with optional support for ranges, negatives and percentages.
*/
public abstract class FloatCondition extends CITCondition {
/**
* Whether this condition should accept given ranges/negatives/percentages.
*/
protected final boolean supportsRanges, supportsNegatives, supportsPercentages;
/**
* If ranges are accepted, parsed minimum/maximum float. If not, minimum is the parsed value.
*/
protected float min, max;
/**
* Whether the parsed value is a range/percentage.
*/
protected boolean range = false, percentage = false;
protected FloatCondition(boolean supportsRanges, boolean supportsNegatives, boolean supportsPercentages) {
this.supportsRanges = supportsRanges;
this.supportsNegatives = supportsNegatives;
this.supportsPercentages = supportsPercentages;
}
/**
* Converts the given context to a float to compare the parsed value to.
* @param context context to retrieve the compared value from
* @return the float value associated with the given context
*/
protected float getValue(CITContext context) {
throw new AssertionError("Not implemented by this condition");
}
/**
* Converts the given context to a max float to be used when percentages are enabled.
* @param context context to retrieve the max value from
* @return the max float value associated with the given context
*/
protected float getPercentageTotalValue(CITContext context) {
throw new AssertionError("Not implemented by this condition");
}
@Override
public void load(PropertyValue value, PropertyGroup properties) throws CITParsingException {
String strValue = value.value();
if (supportsPercentages && (percentage = strValue.contains("%")))
strValue = strValue.replace("%", "");
try {
if (range = supportsRanges) {
if (supportsNegatives) {
switch (strValue.length() - strValue.replace("-", "").length()) { // dashesCount
case 0 -> {
range = false;
min = parseFloat(strValue);
}
case 1 -> {
if (strValue.startsWith("-")) {
range = false;
min = parseFloat(strValue);
} else if (strValue.endsWith("-")) {
min = parseFloat(strValue.substring(0, strValue.length() - 1));
max = MAX_VALUE;
} else {
String[] split = strValue.split("-");
min = parseFloat(split[0]);
max = parseFloat(split[1]);
}
}
case 2 -> {
if (strValue.startsWith("--")) {
min = MIN_VALUE;
max = parseFloat(strValue.substring(1));
} else if (strValue.startsWith("-") && strValue.endsWith("-")) {
min = parseFloat(strValue.substring(0, strValue.length() - 1));
max = MAX_VALUE;
} else if (strValue.startsWith("-") && !strValue.endsWith("-") && !strValue.contains("--")) {
int lastDash = strValue.lastIndexOf('-');
min = parseFloat(strValue.substring(0, lastDash));
max = parseFloat(strValue.substring(lastDash + 1));
} else
throw new CITParsingException("Could not parse range", properties, value.position());
}
case 3 -> {
if (!strValue.contains("---") && strValue.startsWith("-")) {
String[] split = strValue.split("--");
if (split.length != 2 || split[0].isEmpty() || split[1].isEmpty())
throw new CITParsingException("Could not parse range", properties, value.position());
min = parseFloat(split[0]);
max = -parseFloat(split[1]);
} else
throw new CITParsingException("Could not parse range", properties, value.position());
}
default -> throw new CITParsingException("Could not parse range", properties, value.position());
}
} else {
if (range = strValue.contains("-")) {
if (strValue.contains("--"))
throw new CITParsingException("Could not parse range", properties, value.position());
String[] split = strValue.split("-");
switch (split.length) {
case 1 -> {
min = parseFloat(split[0]);
max = MAX_VALUE;
}
case 2 -> {
if (strValue.endsWith("-"))
throw new CITParsingException("Could not parse range", properties, value.position());
min = split[0].isEmpty() ? MIN_VALUE : parseFloat(split[0]);
max = split[1].isEmpty() ? MAX_VALUE : parseFloat(split[1]);
}
default -> throw new CITParsingException("Could not parse range", properties, value.position());
}
} else
min = parseFloat(strValue);
}
} else {
min = parseFloat(strValue);
if (!supportsNegatives && min < 0)
throw new CITParsingException("Negatives are not allowed", properties, value.position());
}
if (range) {
if (min == max)
range = false;
else if (min > max)
throw new CITParsingException("Could not parse range", properties, value.position());
}
} catch (Exception e) {
throw e instanceof CITParsingException citE ? citE : new CITParsingException("Could not parse float", properties, value.position(), e);
}
}
@Override
public boolean test(CITContext context) {
float value = getValue(context);
if (percentage) {
float percentValue = 100f * value / getPercentageTotalValue(context);
return range ? min <= percentValue && percentValue <= max : percentValue == min;
} else
return range ? min <= value && value <= max : value == min;
}
}
|