package com.lifeknight.relaymchub.cosmetics; import com.lifeknight.relaymchub.Main; import com.lifeknight.relaymchub.cosmetics.types.ItemApplication; import com.lifeknight.relaymchub.player.HubPlayer; import com.lifeknight.relaymcutils.player.SmartItem; import com.lifeknight.relaymcutils.utilities.SmartNPC; import com.lifeknight.relayutils.basic.Miscellaneous; import com.lifeknight.relayutils.player.cosmetics.Cosmetic; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public abstract class PhysicalCosmetic extends CooldownCosmetic { private final Map blueprint = new HashMap<>(); private final double duration; private final Map instances = new HashMap<>(); public PhysicalCosmetic(Cosmetic original, int duration) { super(original); this.duration = duration; this.cooldown = duration + 5; this.createBlueprint(); SmartItem smartItem = new SmartItem(this.getOriginal().getRepresentative(), this.getPrettyName(), this.getDescriptionArray()); smartItem.onPlayerClick((player, b, b2) -> this.use(HubPlayer.getHubPlayer(player), b)); this.addApplication(new ItemApplication(1, smartItem)); } public void use(HubPlayer hubPlayer, boolean rightClick) { if (this.hasCooldown()) { if (hubPlayer.enoughSecondsHaveElapsed(this.getCodeName(), this.cooldown)) { if (this.onUse(hubPlayer, rightClick)) { hubPlayer.updateCooldown(this.getCodeName()); } } else { hubPlayer.showCooldownWarning(this.getCodeName(), this.cooldown); } } else { this.onUse(hubPlayer, rightClick); } } public abstract void createBlueprint(); public void put(int x, int y, int z, Material material) { this.clear(x, y, z); this.blueprint.put(new Vector(x, y, z), material); } protected void putSolid(int x1, int y1, int z1, int x2, int y2, int z2, Material material) { for (int x = x1; x <= x2; x++) { for (int y = y1; y <= y2; y++) { for (int z = z1; z <= z2; z++) { this.put(x, y, z, material); } } } } protected void putPlatform(int x1, int z1, int x2, int z2, int y, Material material) { this.putSolid(x1, y, z1, x2, y, z2, material); } @Override public void tick(HubPlayer hubPlayer) { for (Instance value : this.instances.values()) { if (value.owner == hubPlayer) { value.ticks++; } } for (Instance value : instances.values()) { this.tickInstance(value); } } public void tickInstance(Instance instance) { } public boolean place(HubPlayer hubPlayer, Location location) { for (Vector vector : blueprint.keySet()) { Location prospectiveLocation = location.clone().add(vector); if (!(prospectiveLocation.getBlock().getType().isAir() || prospectiveLocation.getBlock().getType() == Material.LIGHT)) { return false; } for (SmartNPC smartNPC : SmartNPC.getSmartNPCs()) { if (smartNPC.getLocation().distance(location.toVector()) < 5) { return false; } } } List unit = new ArrayList<>(); for (Vector vector : this.blueprint.keySet()) { Location prospectiveLocation = location.clone().add(vector); Block block = prospectiveLocation.getBlock(); unit.add(block); block.setType(this.blueprint.get(vector)); } long time = System.currentTimeMillis(); this.instances.put(time, new Instance(unit, hubPlayer, location)); Main.scheduleSyncDelayedTask(() -> this.reset(time), this.duration); return true; } private void reset(long time) { Instance instance = this.instances.remove(time); if (instance != null) { for (int i = 0; i < instance.blocks.size(); i++) { Main.scheduleSyncDelayedTask(() -> { Block block = Miscellaneous.getRandomEntry(instance.blocks); block.setType(Material.AIR); instance.blocks.remove(block); }, i / 20D); } } } protected void clear(int x, int y, int z) { for (Vector vector : Miscellaneous.getList(this.blueprint.keySet())) { if (vector.distance(new Vector(x, y, z)) == 0) { this.blueprint.remove(vector); } } } @Override public PhysicalCosmetic setCooldown(double seconds) { return (PhysicalCosmetic) super.setCooldown(seconds); } static class Instance { private final List blocks; public final long time; public int ticks = 0; private final HubPlayer owner; final Location center; public Instance(List blocks, HubPlayer owner, Location center) { this.blocks = blocks; this.time = System.currentTimeMillis(); this.owner = owner; this.center = center; } } }