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
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import net.supremesurvival.supremecore.mobUtils.HorseInfo;
import net.supremesurvival.supremecore.sanguine.Vampire;
import net.supremesurvival.supremecore.realestate.RealEstateCommand;
import net.supremesurvival.supremecore.loot.LootManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.Listener;
Expand All @@ -31,6 +32,7 @@ public final class SupremeCore extends JavaPlugin implements Listener {
IntervalAnnouncer intervalAnnouncer = new IntervalAnnouncer(this);
FileHandler fileHandler = new FileHandler(this);
Vampire vampire = new Vampire(this);
LootManager lootManager = new LootManager(this);
@Override
public void onEnable() {
// Plugin startup logic
Expand All @@ -46,6 +48,8 @@ public void onEnable() {
Logger.sendMessage((ChatColor.YELLOW + "[SupremeCore] [+] " + ChatColor.GRAY + "SupremeCore loaded - Shit just got real."), Logger.LogType.INFO, "SupremeCore");
this.getServer().getPluginManager().registerEvents(new MobLoot(), this);
Logger.sendMessage((ChatColor.YELLOW + "[SupremeCore] [+] " + ChatColor.GRAY + "SupremeNerf Gold Filter Loaded."), Logger.LogType.INFO, "SupremeCore");
lootManager.enable();
this.getServer().getPluginManager().registerEvents(lootManager, this);
this.getCommand("HorseInfo").setExecutor(new HorseInfo());
this.getCommand("Landmarks").setExecutor(new LandmarkCommand());
this.getCommand("Vampire").setExecutor(vampire);
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/net/supremesurvival/supremecore/loot/LootChest.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
package net.supremesurvival.supremecore.loot;

import org.bukkit.NamespacedKey;
import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.persistence.PersistentDataType;

public class LootChest {
private final TileState tileState;
private final NamespacedKey injectedKey;

public LootChest(BlockState state, NamespacedKey injectedKey) {
if (!(state instanceof TileState tile)) {
throw new IllegalArgumentException("LootChest requires a TileState");
}
this.tileState = tile;
this.injectedKey = injectedKey;
}

public boolean hasInjectedLoot() {
Byte value = tileState.getPersistentDataContainer().get(injectedKey, PersistentDataType.BYTE);
return value != null && value == (byte) 1;
}

public void markInjected() {
tileState.getPersistentDataContainer().set(injectedKey, PersistentDataType.BYTE, (byte) 1);
tileState.update(true, false);
}
}
123 changes: 122 additions & 1 deletion src/main/java/net/supremesurvival/supremecore/loot/LootManager.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,125 @@
package net.supremesurvival.supremecore.loot;

public class LootManager {
import net.supremesurvival.supremecore.SupremeCore;
import net.supremesurvival.supremecore.artefacts.Artefact;
import net.supremesurvival.supremecore.artefacts.ArtefactManager;
import net.supremesurvival.supremecore.commonUtils.Logger;
import net.supremesurvival.supremecore.commonUtils.fileHandler.ConfigUtility;
import net.supremesurvival.supremecore.tomes.Tome;
import net.supremesurvival.supremecore.tomes.TomeManager;
import org.bukkit.NamespacedKey;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.Lootable;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class LootManager implements Listener {
private static final String HANDLE = "Loot";

private final SupremeCore plugin;
private final Random random = new Random();
private final NamespacedKey injectedKey;

private double tomeChance;
private double artefactChance;
private int maxRollsPerChest;
private boolean requireLootTable;

public LootManager(SupremeCore plugin) {
this.plugin = plugin;
this.injectedKey = new NamespacedKey(plugin, "loot_injected");
}

public void enable() {
FileConfiguration config = ConfigUtility.getModuleConfig("Loot");
this.tomeChance = clampChance(config.getDouble("injection.tome-chance", 0.12));
this.artefactChance = clampChance(config.getDouble("injection.artefact-chance", 0.04));
this.maxRollsPerChest = Math.max(1, config.getInt("injection.max-rolls", 1));
this.requireLootTable = config.getBoolean("injection.require-loot-table", true);

Logger.sendMessage("Loot module enabled. tomeChance=" + tomeChance + ", artefactChance=" + artefactChance,
Logger.LogType.INFO, HANDLE);
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryOpen(InventoryOpenEvent event) {
if (!(event.getPlayer() instanceof Player)) {
return;
}

Inventory inventory = event.getInventory();
if (!(inventory.getHolder() instanceof Chest chest)) {
return;
}

BlockState state = chest.getBlock().getState();
if (!(state instanceof Lootable lootable)) {
return;
}

if (requireLootTable && lootable.getLootTable() == null) {
return;
}

LootChest lootChest = new LootChest(state, injectedKey);
if (lootChest.hasInjectedLoot()) {
return;
}

injectRandomLoot(inventory);
lootChest.markInjected();
}

private void injectRandomLoot(Inventory inventory) {
List<ItemStack> rewards = new ArrayList<>();

for (int i = 0; i < maxRollsPerChest; i++) {
if (random.nextDouble() <= tomeChance) {
Tome tome = randomTome();
if (tome != null) {
rewards.add(tome.getItem());
}
}
if (random.nextDouble() <= artefactChance) {
Artefact artefact = randomArtefact();
if (artefact != null) {
rewards.add(artefact.getItem());
}
}
}

for (ItemStack reward : rewards) {
inventory.addItem(reward);
}
}

private Tome randomTome() {
if (TomeManager.tomes.isEmpty()) {
return null;
}
return TomeManager.tomes.get(random.nextInt(TomeManager.tomes.size()));
}

private Artefact randomArtefact() {
if (ArtefactManager.artefacts.isEmpty()) {
return null;
}
return ArtefactManager.artefacts.get(random.nextInt(ArtefactManager.artefacts.size()));
}

private double clampChance(double value) {
if (value < 0.0) return 0.0;
return Math.min(value, 1.0);
}
}
12 changes: 12 additions & 0 deletions src/main/resources/Loot/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
injection:
# Chance (0.0 - 1.0) to inject one random tome per roll.
tome-chance: 0.12

# Chance (0.0 - 1.0) to inject one random artefact per roll.
artefact-chance: 0.04

# How many roll attempts happen on first valid open.
max-rolls: 1

# If true, only chests with a loot table (generated world chests) are targeted.
require-loot-table: true