Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>17.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

</project>
16 changes: 16 additions & 0 deletions src/main/java/ru/meloncode/xmas/Events.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.Nullable;
import ru.meloncode.xmas.utils.TextUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
Expand Down Expand Up @@ -293,4 +296,17 @@ private void disableFireworkDamage(EntityDamageByEntityEvent e)
}
}
}

@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
private void chunkLoad(ChunkLoadEvent e)
{
Collection<MagicTree> trees = XMas.getAllTreesInChunk(e.getChunk());
if(trees == null)
return;
for(MagicTree tree : trees)
{
if(tree.hasScheduledPresents())
tree.spawnScheduledPresents();
}
}
}
74 changes: 52 additions & 22 deletions src/main/java/ru/meloncode/xmas/MagicTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public class MagicTree {
private final UUID owner;
private final Location location;
private final UUID treeuid;
private final Set<Block> presents = new HashSet<>();
TreeLevel level;
private Map<Material, Integer> levelupRequirements;
private Set<Block> blocks;
private long presentCounter = 0;
private long presentCounter;
private int scheduledPresents;

public MagicTree(UUID owner, TreeLevel level, Location location) {
this.treeuid = UUID.randomUUID();
Expand All @@ -35,16 +35,22 @@ public MagicTree(UUID owner, TreeLevel level, Location location) {
this.levelupRequirements = new HashMap<>(level.getLevelupRequirements());
if (Main.inProgress)
build();
presentCounter = 0;
scheduledPresents = 0;
}

public MagicTree(UUID owner, UUID uid, TreeLevel level, Location location, Map<Material, Integer> levelupRequirements) {
public MagicTree(UUID owner, UUID uid, TreeLevel level, Location location, Map<Material, Integer> levelupRequirements,
long presentCounter, int scheduledPresents) {
this.owner = owner;
this.treeuid = uid;
this.level = level;
this.location = location;
this.levelupRequirements = new HashMap<>(levelupRequirements);
this.presentCounter = 0;
this.presentCounter = presentCounter;
if (Main.inProgress)
build();
this.scheduledPresents = scheduledPresents;
}

public static MagicTree getTreeByBlock(Block block) {
Expand Down Expand Up @@ -186,29 +192,35 @@ public void build() {

@SuppressWarnings("deprecation")
public void spawnPresent() {
if(!location.getWorld().isChunkLoaded((int)location.getX() / 16, (int)location.getZ() / 16))
{
if(scheduledPresents + 1 <= 8)
scheduledPresents++;
return;
}

Location presentLoc = location.clone().add(-1 + Main.RANDOM.nextInt(3), 0, -1 + Main.RANDOM.nextInt(3));

Block pBlock = presentLoc.getBlock();
if (presents.size() <= 3) {
if (!pBlock.getType().isSolid() && pBlock.getType() != Material.SPRUCE_SAPLING) {
pBlock.setType(Material.PLAYER_HEAD);
BlockState state = pBlock.getState();
if (state instanceof Skull) {
Skull skull = (Skull) state;
BlockFace face;
do {
face = BlockFace.values()[Main.RANDOM.nextInt(BlockFace.values().length)];
}
while (face == BlockFace.DOWN || face == BlockFace.UP || face == BlockFace.SELF);
//skull.setRotation(face);
Rotatable skullRotatable = (Rotatable) skull.getBlockData();
skullRotatable.setRotation(face);
//skull.setSkullType(SkullType.PLAYER);
skull.setType(Material.PLAYER_HEAD);
//skull.setOwner();
skull.setOwningPlayer(Bukkit.getOfflinePlayer(Main.getHeads().get(Main.RANDOM.nextInt(Main.getHeads().size()))));
skull.update(true);
if (!pBlock.getType().isSolid() && pBlock.getType() != Material.SPRUCE_SAPLING)
{
pBlock.setType(Material.PLAYER_HEAD);
BlockState state = pBlock.getState();
if (state instanceof Skull) {
Skull skull = (Skull) state;
BlockFace face;
do {
face = BlockFace.values()[Main.RANDOM.nextInt(BlockFace.values().length)];
}
while (face == BlockFace.DOWN || face == BlockFace.UP || face == BlockFace.SELF);
//skull.setRotation(face);
Rotatable skullRotatable = (Rotatable) skull.getBlockData();
skullRotatable.setRotation(face);
//skull.setSkullType(SkullType.PLAYER);
skull.setType(Material.PLAYER_HEAD);
//skull.setOwner();
skull.setOwningPlayer(Bukkit.getOfflinePlayer(Main.getHeads().get(Main.RANDOM.nextInt(Main.getHeads().size()))));
skull.update(true);
}
}
}
Expand Down Expand Up @@ -279,4 +291,22 @@ public void end() {
}
XMas.removeTree(this);
}

public long getPresentCounter() {
return presentCounter;
}

public int getScheduledPresents() {
return scheduledPresents;
}

public boolean hasScheduledPresents() {
return scheduledPresents > 0;
}

public void spawnScheduledPresents() {
for(int i = scheduledPresents; i > 0; i--)
spawnPresent();
scheduledPresents = 0;
}
}
9 changes: 8 additions & 1 deletion src/main/java/ru/meloncode/xmas/TreeSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public static void loadTrees(JavaPlugin plugin, World world) {
TreeLevel level;
int x, y, z;
Location loc;
long presentCounter;
int scheduledPresents;
if (trees.getConfigurationSection("trees") != null && trees.getConfigurationSection("trees").getKeys(false).size() > 0) {

for (String cKey : trees.getConfigurationSection("trees").getKeys(false)) {
Expand All @@ -44,7 +46,10 @@ public static void loadTrees(JavaPlugin plugin, World world) {
} else {
requirements = new HashMap<>();
}
XMas.addMagicTree(new MagicTree(owner, treeUID, level, loc, requirements));
presentCounter = trees.getLong("trees." + cKey + ".present_counter", 0);
scheduledPresents = trees.getInt("trees." + cKey + ".scheduled_presents", 0);

XMas.addMagicTree(new MagicTree(owner, treeUID, level, loc, requirements, presentCounter, scheduledPresents));
} catch (Exception e) {
plugin.getLogger().severe(String.format("Error while loading tree `%s`", cKey));
e.printStackTrace();
Expand Down Expand Up @@ -76,6 +81,8 @@ public static void saveTree(MagicTree tree) {
} catch (IOException e) {
e.printStackTrace();
}
trees.set("trees." + cKey + ".present_counter", tree.getPresentCounter());
trees.set("trees." + cKey + ".scheduled_presents", tree.getScheduledPresents());
}

public static void removeTree(MagicTree tree) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ru/meloncode/xmas/XMas.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package ru.meloncode.xmas;

import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Skull;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import ru.meloncode.xmas.utils.LocationUtils;
import ru.meloncode.xmas.utils.TextUtils;

import java.util.ArrayList;
Expand All @@ -20,11 +23,13 @@
class XMas {

private static final ConcurrentHashMap<UUID, MagicTree> trees = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Long, List<MagicTree>> trees_byChunk = new ConcurrentHashMap<>();
public static ItemStack XMAS_CRYSTAL;

public static void createMagicTree(Player player, Location loc) {
MagicTree tree = new MagicTree(player.getUniqueId(), TreeLevel.SAPLING, loc);
trees.put(tree.getTreeUID(), tree);
trees_byChunk.computeIfAbsent(LocationUtils.getChunkKey(tree.getLocation()), aLong -> new ArrayList<>()).add(tree);
tree.save();
}

Expand All @@ -37,10 +42,16 @@ public static Collection<MagicTree> getAllTrees() {
return trees.values();
}

@Nullable
public static Collection<MagicTree> getAllTreesInChunk(Chunk chunk) {
return trees_byChunk.get(LocationUtils.getChunkKey(chunk));
}

public static void removeTree(MagicTree tree) {
tree.unbuild();
TreeSerializer.removeTree(tree);
trees.remove(tree.getTreeUID());
trees_byChunk.remove(LocationUtils.getChunkKey(tree.getLocation()));
}

public static void processPresent(Block block, Player player) {
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/ru/meloncode/xmas/utils/LocationUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.meloncode.xmas.utils;

import org.bukkit.Chunk;
import org.bukkit.Location;

public class LocationUtils {
public static long getChunkKey(Chunk chunk) {
return getChunkKey(chunk.getX(), chunk.getZ());
}
public static long getChunkKey(Location location) {
return getChunkKey(location.getBlockX(), location.getBlockZ());
}

public static long getChunkKey(int x, int z) {
x = floor(x) >> 4;
z = floor(z) >> 4;
return (((long) x) << 32) | (z & 0xFFFFFFFFL);
}

public static int floor(double num) {
int floor = (int) num;
return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63);
}
}