DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamEntityMask.java
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Dreamfire Studio
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package com.dreamfirestudios.dreamcore.DreamEntityMask;
25
26import com.dreamfirestudios.dreamcore.DreamCore;
27import com.dreamfirestudios.dreamcore.DreamVanish.DreamVanish;
28import lombok.Getter;
29import org.bukkit.entity.Entity;
30import org.bukkit.entity.EntityType;
31import org.bukkit.entity.LivingEntity;
32import org.bukkit.entity.Player;
33
34import java.util.ArrayList;
35import java.util.List;
36import java.util.UUID;
37
47
48public class DreamEntityMask {
49
51 @Getter private Player player;
52
54 private boolean deleteMaskOnNull;
55
57 @Getter private double minDistance;
58
60 @Getter private double maxDistance;
61
63 private EntityMaskType entityMaskType;
64
66 private final List<EntityType> entityTypeExceptions = new ArrayList<>();
67
69 private final List<UUID> uuidExceptions = new ArrayList<>();
70
72 private List<Entity> lastFrameEntities = new ArrayList<>();
73
75 @Getter private boolean actionBarPaused = true;
76
77 // ---------------- Exceptions ----------------
78
84
85 public void addToExceptions(EntityType entityType){
86 if (!entityTypeExceptions.contains(entityType)) {
87 entityTypeExceptions.add(entityType);
88 }
89 }
90
96
97 public void addToExceptions(UUID entityUUID){
98 if (!uuidExceptions.contains(entityUUID)) {
99 uuidExceptions.add(entityUUID);
100 }
101 }
102
103 // ---------------- Frame update ----------------
104
114
115 public void displayNextFrame(){
116 if (player == null || !player.isOnline() || actionBarPaused) return;
117
118 var newEntityStates = new ArrayList<Entity>();
119
120 var playerWorld = player.getWorld();
121 for (var entity : playerWorld.getEntities()){
122 if (entityTypeExceptions.contains(entity.getType())) continue;
123 if (uuidExceptions.contains(entity.getUniqueId())) continue;
124 if (!isCorrectForMaskType(entity)) continue;
125
126 double distance = player.getLocation().distance(entity.getLocation());
127 if (distance < minDistance || distance > maxDistance) continue;
128
129 newEntityStates.add(entity);
130 }
131
132 // Reveal old entities, hide new ones
133 for (var entity : lastFrameEntities) DreamVanish.showTargetToViewer(entity, player);
134 for (var entity : newEntityStates) DreamVanish.hideTargetFromViewer(entity, player);
135
136 lastFrameEntities = newEntityStates;
137 }
138
145
146 private boolean isCorrectForMaskType(Entity entity){
147 return switch (entityMaskType) {
148 case Entity -> true;
149 case LivingEntity -> entity instanceof LivingEntity;
150 case Player -> entity instanceof Player;
151 };
152 }
153
154 // ---------------- Lifecycle ----------------
155
160
161 public void pause() {
162 if (!actionBarPaused){
163 actionBarPaused = true;
164 new EntityMaskPausedEvent(this);
165 for (var entity : lastFrameEntities) DreamVanish.showTargetToViewer(entity, player);
166 }
167 }
168
173
174 public void play() {
175 if (actionBarPaused){
176 actionBarPaused = false;
177 new EntityMaskStartedEvent(this);
178 }
179 }
180
186
188 actionBarPaused = true;
189 new EntityMaskStoppedEvent(this);
190 for (var entity : lastFrameEntities) DreamVanish.showTargetToViewer(entity, player);
191
192 return DreamCore.DreamEntityMasks.remove(player.getUniqueId());
193 }
194
195 // ---------------- Builder ----------------
196
201
202 public static class Builder {
203 private boolean deleteMaskOnNull = false;
204 private double minDistance = 0;
205 private double maxDistance = 5;
206 private EntityMaskType entityMaskType = EntityMaskType.Player;
207 private final List<UUID> uuidExceptions = new ArrayList<>();
208 private final List<EntityType> entityTypeExceptions = new ArrayList<>();
209
212
213 public Builder entityTypeExceptions(List<EntityType> exceptions){
214 for (var type : exceptions) {
215 if (!entityTypeExceptions.contains(type)) entityTypeExceptions.add(type);
216 }
217 return this;
218 }
219
222
223 public Builder uuidExceptions(List<UUID> exceptions){
224 for (var id : exceptions) {
225 if (!uuidExceptions.contains(id)) uuidExceptions.add(id);
226 }
227 return this;
228 }
229
231 public Builder deleteMaskOnNull(boolean deleteMaskOnNull){
232 this.deleteMaskOnNull = deleteMaskOnNull;
233 return this;
234 }
235
237 public Builder minDistance(double minDistance){
238 this.minDistance = minDistance;
239 return this;
240 }
241
243 public Builder maxDistance(double maxDistance){
244 this.maxDistance = maxDistance;
245 return this;
246 }
247
249 public Builder entityMaskType(EntityMaskType entityMaskType){
250 this.entityMaskType = entityMaskType;
251 return this;
252 }
253
260
261 public DreamEntityMask CreateMask(Player player){
262 if (player == null) throw new IllegalArgumentException("Player cannot be null");
263
264 var storedMask = DreamCore.DreamEntityMasks.getOrDefault(player.getUniqueId(), null);
265 if (storedMask != null){
266 entityTypeExceptions.forEach(storedMask::addToExceptions);
267 uuidExceptions.forEach(storedMask::addToExceptions);
268 return storedMask;
269 }
270
271 var createdMask = new DreamEntityMask();
272 createdMask.player = player;
273 createdMask.deleteMaskOnNull = deleteMaskOnNull;
274 createdMask.minDistance = minDistance;
275 createdMask.maxDistance = maxDistance;
276 createdMask.entityMaskType = entityMaskType;
277
278 entityTypeExceptions.forEach(createdMask::addToExceptions);
279 uuidExceptions.forEach(createdMask::addToExceptions);
280
281 new EntityMaskCreateEvent(createdMask, player);
282 return DreamCore.DreamEntityMasks.put(player.getUniqueId(), createdMask);
283 }
284 }
285}
static final LinkedHashMap< UUID, DreamEntityMask > DreamEntityMasks
Builder deleteMaskOnNull(boolean deleteMaskOnNull)
Configures whether to delete mask on null player reference.
Builder minDistance(double minDistance)
Sets the minimum distance for the mask.
Builder maxDistance(double maxDistance)
Sets the maximum distance for the mask.
Builder entityMaskType(EntityMaskType entityMaskType)
Sets the mask type filter.
Fired when a DreamEntityMask is created and registered for a player.