Unknown Log

#HiOsflb
461 lines
Raw
1import org.bukkit.Location;
2import org.bukkit.Material;
3import org.bukkit.entity.ArmorStand;
4import org.bukkit.entity.Player;
5import org.bukkit.inventory.ItemStack;
6import org.bukkit.util.Vector;
7import org.bukkit.block.Block;
8import org.bukkit.scheduler.BukkitRunnable;
9import org.bukkit.util.EulerAngle;
10import org.bukkit.configuration.file.FileConfiguration;
11import org.bukkit.inventory.PlayerInventory;
12import java.util.Arrays;
13import java.util.HashSet;
14import java.util.Set;
15import org.bukkit.entity.Entity;
16import org.bukkit.event.entity.EntityDamageEvent;
17
18
19public class DrillVehicle {
20    private final Player owner;
21    private final ArmorStand mainStand;
22    private final Set<ArmorStand> modelParts = new HashSet<>();
23    private double fuel = 100.0;
24    private boolean isDrilling = false;
25    private boolean isMoving = false;
26    private ArmorStand drillHead;
27    private boolean fuelMessageSent = false;
28    private float currentYaw = 0;
29    private static final double MOUNT_HEIGHT_OFFSET = -0.2;
30
31
32    public boolean isPartOfDrill(ArmorStand stand) {
33    return modelParts.contains(stand);
34}
35
36
37    private static final Set<Material> UNBREAKABLE_BLOCKS = new HashSet<>(Arrays.asList(
38        Material.BEDROCK,
39        Material.OBSIDIAN,
40        Material.BARRIER,
41        Material.END_PORTAL_FRAME,
42        Material.END_PORTAL,
43        Material.NETHER_PORTAL
44    ));
45
46
47    public DrillVehicle(Player owner) {
48        this.owner = owner;
49        Location spawnLoc = owner.getLocation();
50        spawnLoc.setY(spawnLoc.getY() + 0.1);
51        spawnLoc.setYaw(0);
52        currentYaw = 0;
53       
54        mainStand = spawnLoc.getWorld().spawn(spawnLoc, ArmorStand.class);
55        mainStand.setVisible(false);
56        mainStand.setGravity(false);
57        mainStand.setInvulnerable(true);
58        mainStand.setBasePlate(false);
59        mainStand.setArms(false);
60        mainStand.setSmall(false);
61        mainStand.setMarker(true);
62        mainStand.setCanPickupItems(false);
63        mainStand.setRemoveWhenFarAway(false);
64       
65        createDrillModel();
66        startHandlers();
67    }
68
69
70    private void createDrillModel() {
71        Location loc = mainStand.getLocation();
72       
73        // Base platform (2x3 flat platform)
74        double spacing = 0.4;
75        for (int x = -1; x <= 1; x++) {
76            for (int z = -1; z <= 1; z++) {
77                createBodyPart(loc, x * spacing, 0, z * spacing, Material.IRON_BLOCK);
78            }
79        }
80
81
82        // Walls (1 block high, on the edges) - now 0.75x height
83        double wallHeight = 1.2;
84       
85        // Left and right walls with glass
86        for (double y = 0.4; y <= wallHeight; y += 0.4) {
87            // Left wall
88            createBodyPart(loc, -spacing, y, -spacing, Material.BLACK_CONCRETE);
89            createBodyPart(loc, -spacing, y, 0, Material.GLASS);
90            createBodyPart(loc, -spacing, y, spacing, Material.BLACK_CONCRETE);
91           
92            // Right wall
93            createBodyPart(loc, spacing, y, -spacing, Material.BLACK_CONCRETE);
94            createBodyPart(loc, spacing, y, 0, Material.GLASS);
95            createBodyPart(loc, spacing, y, spacing, Material.BLACK_CONCRETE);
96           
97            // Back wall (between concrete)
98            createBodyPart(loc, 0, y, -spacing, Material.GLASS);
99        }
100
101
102        // 3x3 Gold connection platform (without glass on top)
103        for (double y = 0.4; y <= 0.8; y += 0.4) {
104            for (int x = -1; x <= 1; x++) {
105                createBodyPart(loc, x * 0.4, y, 0.8, Material.GOLD_BLOCK);
106            }
107        }
108
109
110        // Front drill assembly
111        createBodyPart(loc, -0.2, 0.5, 1.2, Material.DIAMOND_BLOCK);
112        createBodyPart(loc, 0.2, 0.5, 1.2, Material.DIAMOND_BLOCK);
113        createBodyPart(loc, 0, 0.9, 1.2, Material.DIAMOND_BLOCK);
114       
115        drillHead = createModelPart(loc.clone().add(0, 0.7, 1.6));
116        drillHead.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_BLOCK));
117        drillHead.setSmall(true);
118        modelParts.add(drillHead);
119       
120        // Make all parts non-pickupable
121        for (ArmorStand part : modelParts) {
122            part.setCanPickupItems(false);
123        }
124    }
125    // This method handles the vehicle controls for WASD movement
126    public void handleVehicleControls(float forward, float sideways, boolean jump) {
127        if (owner.getVehicle() != mainStand || fuel <= 0) {
128            if (!fuelMessageSent && fuel <= 0) {
129                owner.sendMessage("§cOUT OF FUEL");
130                fuelMessageSent = true;
131            }
132            return;
133        }
134
135
136        // Make sure player is still mounted
137        if (owner.getVehicle() != mainStand) {
138            mount(); // Try to remount if somehow dismounted
139            return;
140        }
141
142
143        double baseSpeed = DrillPlugin.getInstance().getConfig().getDouble("movement-speed", 0.3);
144       
145        if (forward != 0 || sideways != 0) {
146            // Calculate movement vectors
147            double yaw = Math.toRadians(currentYaw);
148            Vector direction = new Vector(-Math.sin(yaw), 0, Math.cos(yaw));
149            Vector right = new Vector(-direction.getZ(), 0, direction.getX());
150           
151            // Combine movements
152            Vector movement = direction.multiply(forward).add(right.multiply(-sideways));
153            movement.normalize().multiply(baseSpeed);
154           
155            // Apply movement
156            Location newLoc = mainStand.getLocation().add(movement);
157            if (newLoc.getBlock().getType() == Material.AIR) {
158                newLoc.setYaw(currentYaw);
159                mainStand.teleport(newLoc);
160               
161                // Keep player in sync
162                Location playerLoc = newLoc.clone();
163                playerLoc.setY(newLoc.getY() + MOUNT_HEIGHT_OFFSET);
164                playerLoc.setYaw(currentYaw);
165                owner.teleport(playerLoc);
166               
167                updateModelParts();
168                consumeFuel(0.1);
169            }
170        }
171       
172            if (jump) {
173            currentYaw = (currentYaw + 180) % 360;
174            Location loc = mainStand.getLocation();
175            loc.setYaw(currentYaw);
176            mainStand.teleport(loc);
177           
178            Location playerLoc = owner.getLocation();
179            playerLoc.setYaw(currentYaw);
180            owner.teleport(playerLoc);
181           
182            updateModelParts();
183        }
184    }
185    private void startHandlers() {
186        new BukkitRunnable() {
187            u/Override
188            public void run() {
189                if (!mainStand.isValid() || !owner.isOnline()) {
190                    remove();
191                    cancel();
192                    return;
193                }
194               
195                if (isDrilling) {
196                    handleDrilling();
197                }
198            }
199        }.runTaskTimer(DrillPlugin.getInstance(), 1L, 1L);
200    }
201    public void toggleMovement() {
202        isMoving = !isMoving;
203        String message = isMoving ?
204            DrillPlugin.getInstance().getConfig().getString("messages.movement-activated", "§aDrill movement activated!") :
205            DrillPlugin.getInstance().getConfig().getString("messages.movement-deactivated", "§cDrill movement deactivated!");
206        owner.sendMessage(message);
207    }
208
209
210  private void handleMovement() {
211        if (fuel <= 0) {
212            if (!fuelMessageSent) {
213                owner.sendMessage("§cOUT OF FUEL");
214                fuelMessageSent = true;
215            }
216            isMoving = false;
217            return;
218        }
219
220
221        Vector direction = owner.getLocation().getDirection().setY(0).normalize();
222        double moveSpeed = DrillPlugin.getInstance().getConfig().getDouble("movement-speed", 0.3);
223        Location currentLoc = mainStand.getLocation();
224        Location newLoc = currentLoc.clone().add(direction.multiply(moveSpeed));
225       
226        if (newLoc.getBlock().getType().equals(Material.AIR)) {
227            // Keep current yaw when moving
228            newLoc.setYaw(currentYaw);
229            mainStand.teleport(newLoc);
230            updateModelParts();
231            consumeFuel(0.1);
232        }
233    }
234
235
236
237    private void handleDrilling() {
238        if (fuel <= 0) {
239            isDrilling = false;
240            return;
241        }
242       
243        if (drillHead != null) {
244            EulerAngle rotation = drillHead.getHeadPose();
245            drillHead.setHeadPose(rotation.add(0, 0.5, 0));
246        }
247       
248        Location loc = mainStand.getLocation();
249        Vector direction = getForwardVector();
250       
251        for (int i = 1; i <= 3; i++) {
252            Location blockLoc = loc.clone().add(direction.clone().multiply(i + 1));
253            for (int y = -1; y <= 1; y++) {
254                for (int x = -1; x <= 1; x++) {
255                    Vector right = new Vector(direction.getZ(), 0, -direction.getX());
256                    Location miningLoc = blockLoc.clone().add(right.multiply(x)).add(0, y, 0);
257                    Block block = miningLoc.getBlock();
258                    if (block.getType() != Material.AIR && !UNBREAKABLE_BLOCKS.contains(block.getType())) {
259                        block.breakNaturally();
260                    }
261                }
262            }
263        }
264       
265        consumeFuel(0.5);
266    }
267
268
269            public void mount() {
270    if (owner != null && mainStand != null) {
271        mainStand.addPassenger(owner);
272       
273        new BukkitRunnable() {
274            u/Override
275            public void run() {
276                Location mountLoc = mainStand.getLocation().clone();
277                mountLoc.setY(mainStand.getLocation().getY() + MOUNT_HEIGHT_OFFSET);
278                mountLoc.setYaw(currentYaw);
279                mountLoc.setPitch(0);
280                owner.teleport(mountLoc);
281               
282                new BukkitRunnable() {
283                    u/Override
284                    public void run() {
285                        mainStand.addPassenger(owner);
286                        Location playerLoc = owner.getLocation();
287                        playerLoc.setYaw(currentYaw);
288                        owner.teleport(playerLoc);
289                    }
290                }.runTaskLater(DrillPlugin.getInstance(), 2L);
291            }
292        }.runTaskLater(DrillPlugin.getInstance(), 1L);
293    } else {
294        if (owner != null) {
295            owner.sendMessage("Failed to mount: mainStand is null");
296        }
297    }
298        }
299   
300
301
302    private Vector getForwardVector() {
303        double rad = Math.toRadians(currentYaw);
304        return new Vector(-Math.sin(rad), 0, Math.cos(rad)).normalize();
305    }
306
307
308    private void consumeFuel(double amount) {
309        FileConfiguration config = DrillPlugin.getInstance().getConfig();
310        double maxFuelCapacity = config.getDouble("fuel.max-fuel-capacity", 500);
311
312
313        if (fuel > 0) {
314            fuel -= amount;
315            if (fuel < 0) fuel = 0;
316            fuelMessageSent = false;
317            return;
318        }
319
320
321        PlayerInventory inventory = owner.getInventory();
322        double fuelPerCoal = config.getDouble("fuel.coal-fuel-amount", 50);
323
324
325        ItemStack coal = null;
326        for (ItemStack item : inventory.getContents()) {
327            if (item != null && item.getType() == Material.COAL) {
328                coal = item;
329                break;
330            }
331        }
332
333
334        if (coal != null) {
335            double addedFuel = Math.min(fuelPerCoal, maxFuelCapacity);
336            fuel += addedFuel;
337            coal.setAmount(coal.getAmount() - 1);
338           
339            String message = config.getString("messages.fuel-added", "§aAdded fuel! Current fuel level: §6%fuel%")
340                .replace("%fuel%", String.format("%.1f", fuel));
341            owner.sendMessage(message);
342            fuelMessageSent = false;
343        }
344    }
345
346
347    public void addFuel(ItemStack item) {
348        if (item == null || item.getType() != Material.COAL) {
349            return;
350        }
351
352
353        FileConfiguration config = DrillPlugin.getInstance().getConfig();
354        double maxFuelCapacity = config.getDouble("fuel.max-fuel-capacity", 500);
355        double fuelPerCoal = config.getDouble("fuel.coal-fuel-amount", 50);
356
357
358        double addedFuel = Math.min(fuelPerCoal, maxFuelCapacity - fuel);
359       
360        if (addedFuel > 0) {
361            fuel += addedFuel;
362            item.setAmount(item.getAmount() - 1);
363           
364            String message = config.getString("messages.fuel-added", "§aAdded fuel! Current fuel level: §6%fuel%")
365                .replace("%fuel%", String.format("%.1f", fuel));
366            owner.sendMessage(message);
367            fuelMessageSent = false;
368        }
369    }
370
371
372    public void toggleDrilling() {
373        isDrilling = !isDrilling;
374        String message = isDrilling ?
375            "§aDrill activated!" :
376            "§cDrill deactivated!";
377        owner.sendMessage(message);
378    }
379
380
381    public void dismount() {
382        if (owner.getVehicle() == mainStand) {
383            Location dismountLoc = mainStand.getLocation().clone().add(0, 1.5, 0);
384            owner.leaveVehicle();
385            owner.teleport(dismountLoc);
386        }
387    }
388
389
390    public void rotate() {
391        if (owner.getVehicle() == mainStand) {
392            currentYaw = (currentYaw + 90) % 360;
393            Location loc = mainStand.getLocation();
394            loc.setYaw(currentYaw);
395            mainStand.teleport(loc);
396           
397            Location playerLoc = owner.getLocation();
398            playerLoc.setYaw(currentYaw);
399            owner.teleport(playerLoc);
400           
401            updateModelParts();
402        }
403    }
404
405
406    private void updateModelParts() {
407        Location baseLoc = mainStand.getLocation();
408        for (ArmorStand part : modelParts) {
409            Location partLoc = baseLoc.clone();
410            Vector offset = part.getLocation().subtract(baseLoc).toVector();
411            offset = rotateVector(offset, currentYaw);
412            partLoc.add(offset);
413            partLoc.setYaw(currentYaw);
414            part.teleport(partLoc);
415        }
416    }
417
418
419    private Vector rotateVector(Vector vector, float yaw) {
420        double rad = Math.toRadians(yaw);
421        double x = vector.getX() * Math.cos(rad) - vector.getZ() * Math.sin(rad);
422        double z = vector.getX() * Math.sin(rad) + vector.getZ() * Math.cos(rad);
423        return new Vector(x, vector.getY(), z);
424    }
425
426
427    public void remove() {
428        mainStand.remove();
429        for (ArmorStand part : modelParts) {
430            part.remove();
431        }
432        modelParts.clear();
433    }
434
435
436    public ArmorStand getMainStand() {
437        return mainStand;
438    }
439
440
441    public Player getOwner() {
442        return owner;
443    }
444
445
446    private ArmorStand createModelPart(Location loc) {
447        ArmorStand stand = loc.getWorld().spawn(loc, ArmorStand.class);
448        stand.setVisible(false);
449        stand.setGravity(false);
450        stand.setInvulnerable(true);
451        stand.setSmall(true);
452        modelParts.add(stand);
453        return stand;
454    }
455
456
457    private void createBodyPart(Location loc, double x, double y, double z, Material material) {
458        ArmorStand part = createModelPart(loc.clone().add(x, y, z));
459        part.getEquipment().setHelmet(new ItemStack(material));
460    }
461}
This log will be saved for 90 days from their last view.
Report abuse