46
46
import in .twizmwaz .cardinal .module .filter .type .modifiers .AllFilter ;
47
47
import in .twizmwaz .cardinal .module .filter .type .modifiers .TransformFilter ;
48
48
import in .twizmwaz .cardinal .module .objective .Objective ;
49
+ import in .twizmwaz .cardinal .module .objective .OwnedObjective ;
49
50
import in .twizmwaz .cardinal .module .objective .ProximityMetric ;
50
51
import in .twizmwaz .cardinal .module .region .Region ;
51
52
import in .twizmwaz .cardinal .module .region .type .FiniteBlockRegion ;
53
+ import in .twizmwaz .cardinal .module .scoreboard .displayables .EntryHolder ;
54
+ import in .twizmwaz .cardinal .module .scoreboard .displayables .EntryUpdater ;
52
55
import in .twizmwaz .cardinal .module .team .Team ;
53
56
import in .twizmwaz .cardinal .playercontainer .PlayingPlayerContainer ;
54
57
import in .twizmwaz .cardinal .util .Channels ;
58
+ import in .twizmwaz .cardinal .util .Characters ;
55
59
import in .twizmwaz .cardinal .util .Components ;
56
60
import in .twizmwaz .cardinal .util .MaterialPattern ;
61
+ import in .twizmwaz .cardinal .util .Numbers ;
57
62
import lombok .Getter ;
58
63
import lombok .NonNull ;
59
64
import lombok .Setter ;
70
75
import java .util .UUID ;
71
76
72
77
@ Getter
73
- public class Destroyable extends Objective {
78
+ public class Destroyable extends Objective implements OwnedObjective , EntryUpdater {
74
79
75
80
private final String name ;
76
81
private final Region region ;
@@ -84,7 +89,10 @@ public class Destroyable extends Objective {
84
89
private final ProximityMetric proximityMetric ;
85
90
private final boolean proximityHorizontal ;
86
91
92
+ private final EntryHolder entryHolder = new EntryHolder ();
93
+
87
94
private final List <Player > touchedPlayers = new ArrayList <>();
95
+ private final List <Team > touchedTeams = new ArrayList <>();
88
96
private final Map <UUID , Integer > playerContributions = new HashMap <>();
89
97
90
98
@ Setter
@@ -141,6 +149,21 @@ public Destroyable(Match match, String id, String name, boolean required, Region
141
149
true );
142
150
}
143
151
152
+ public boolean isTouched (Team team ) {
153
+ return touchedTeams .contains (team );
154
+ }
155
+
156
+ /**
157
+ * Sets the destroyable as touched for a certain team. Scoreboard entries will be updated.
158
+ * @param team The team that touched the destroyable.
159
+ */
160
+ public void setTouched (Team team ) {
161
+ if (!isTouched (team )) {
162
+ touchedTeams .add (team );
163
+ entryHolder .updateEntries ();
164
+ }
165
+ }
166
+
144
167
public boolean isPartOf (@ NonNull Block block ) {
145
168
return region .contains (block .getLocation ())
146
169
&& materials .contains (block .getType (), (int ) block .getState ().getMaterialData ().getData ());
@@ -156,6 +179,7 @@ public void addBrokenPiecesFor(Player player, int contribution) {
156
179
PlayingPlayerContainer container = match .getPlayingContainer (player );
157
180
if (!isCompleted () && container instanceof Team ) {
158
181
Team team = (Team ) container ;
182
+ setTouched (team );
159
183
if (show && !touchedPlayers .contains (player )) {
160
184
touchedPlayers .add (player );
161
185
Channels .getTeamChannel (match , team ).sendPrefixedMessage (
@@ -187,9 +211,21 @@ public void addBrokenPiecesFor(Player player, int contribution) {
187
211
} else {
188
212
Bukkit .getPluginManager ().callEvent (new ObjectiveTouchEvent (this , player ));
189
213
}
214
+ entryHolder .updateEntries ();
190
215
}
191
216
}
192
217
218
+ /**
219
+ * Gets the completion percentage.
220
+ * @return The percentage, always between 0 and 100;
221
+ */
222
+ public int getPercent () {
223
+ if (isCompleted ()) {
224
+ return 100 ;
225
+ }
226
+ return (int ) Numbers .between (Math .floor ((double ) broken / (total * completion ) * 100 ), 0 , 100 );
227
+ }
228
+
193
229
private ListComponent getContributionList () {
194
230
List <BaseComponent > contributions = new ArrayList <>();
195
231
playerContributions .forEach ((uuid , amount ) -> {
@@ -201,6 +237,27 @@ private ListComponent getContributionList() {
201
237
return new ListComponent (contributions );
202
238
}
203
239
240
+ /**
241
+ * Gets the monument prefix for a given viewer team, for a specific attacker.
242
+ * @param viewer The viewer team, null for observers.
243
+ * @param attacker The team attacking the objective. Used to see if the team has a touch or not.
244
+ * @return Color and monument state or percentage. Always between 3 and 6 characters (color + "100%").
245
+ */
246
+ @ Override
247
+ public String getPrefix (Team viewer , Team attacker ) {
248
+ if (isCompleted ()) {
249
+ return ChatColor .GREEN + getCompletionOrCharacter (viewer , Characters .CORE_COMPLETED );
250
+ } else if (isTouched (attacker ) && (viewer == null || viewer .equals (attacker ))) {
251
+ return ChatColor .YELLOW + getCompletionOrCharacter (viewer , Characters .CORE_TOUCHED );
252
+ } else {
253
+ return ChatColor .RED + getCompletionOrCharacter (viewer , Characters .CORE_INCOMPLETE );
254
+ }
255
+ }
256
+
257
+ private String getCompletionOrCharacter (Team viewer , Characters character ) {
258
+ return viewer == null || isShowProgress () ? getPercent () + "%" : character + "" ;
259
+ }
260
+
204
261
@ Override
205
262
public UnlocalizedComponent getComponent () {
206
263
return new UnlocalizedComponent (name );
0 commit comments