Skip to content

Commit 860f62b

Browse files
feat: massively reworked item drops
Took 1 hour 7 minutes
1 parent a26ea81 commit 860f62b

17 files changed

Lines changed: 562 additions & 229 deletions

File tree

commons/src/main/java/net/swofty/commons/item/ItemType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ public enum ItemType {
595595
/**
596596
* Shovels
597597
*/
598+
SHEARS(Material.SHEARS, Rarity.COMMON),
598599
WOODEN_SHOVEL(Material.WOODEN_SHOVEL, Rarity.COMMON),
599600
STONE_SHOVEL(Material.STONE_SHOVEL, Rarity.COMMON),
600601
GOLDEN_SHOVEL(Material.GOLDEN_SHOVEL, Rarity.COMMON),

configuration/items/mining/vanilla.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,20 @@ items:
299299
- id: GOLD_ORE
300300
rarity: COMMON
301301
components:
302+
- id: CUSTOM_DROP
303+
rules:
304+
- conditions:
305+
silk_touch: false
306+
drops:
307+
- item: GOLD_INGOT
308+
chance: 1.0
309+
amount: "2-5"
310+
- conditions:
311+
silk_touch: true
312+
drops:
313+
- item: GOLD_ORE
314+
chance: 1.0
315+
amount: 1
302316
- id: PLACEABLE
303317
- id: SKILLABLE_MINE
304318
category: MINING

configuration/items/vanillaItems.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@ items:
66
- id: PLACEABLE
77
- id: SELLABLE
88
value: 1.0
9+
- id: SHORT_GRASS
10+
rarity: COMMON
11+
material: SHORT_GRASS
12+
components:
13+
- id: CUSTOM_DROP
14+
rules:
15+
- conditions:
16+
silk_touch: false
17+
drops:
18+
- item: WHEAT_SEEDS
19+
chance: 0.125
20+
amount: 1
21+
# No grass block drop without silk touch
22+
- conditions:
23+
silk_touch: true
24+
drops:
25+
- item: SHORT_GRASS
26+
chance: 1.0
27+
amount: 1
28+
- id: PLACEABLE
929
- id: GRASS_BLOCK
1030
material: GRASS_BLOCK
1131
rarity: COMMON
@@ -480,10 +500,67 @@ items:
480500
result:
481501
type: CYAN_STAINED_GLASS
482502
amount: 8
503+
- id: OAK_LEAVES
504+
rarity: COMMON
505+
material: oak_leaves
506+
components:
507+
- id: CUSTOM_DROP
508+
rules:
509+
# Silk touch rule - always gives leaves (highest priority)
510+
- conditions:
511+
silk_touch: true
512+
drops:
513+
- item: OAK_LEAVES
514+
chance: 1.0
515+
amount: 1
516+
# Shears rule - gives leaves + normal drops
517+
- conditions:
518+
broken_with: SHEARS
519+
drops:
520+
- item: OAK_LEAVES
521+
chance: 1.0
522+
amount: 1
523+
- item: OAK_SAPLING
524+
chance: 0.05
525+
amount: 1
526+
- item: STICK
527+
chance: 0.02
528+
amount: "1-2"
529+
- item: APPLE
530+
chance: 0.005
531+
amount: 1
532+
# Default rule - no shears, no silk touch
533+
- conditions:
534+
silk_touch: false
535+
broken_with_not: SHEARS
536+
drops:
537+
- item: OAK_SAPLING
538+
chance: 0.05
539+
amount: 1
540+
- item: STICK
541+
chance: 0.02
542+
amount: "1-2"
543+
- item: APPLE
544+
chance: 0.005
545+
amount: 1
546+
- id: PLACEABLE
483547
- id: GLASS
484548
material: GLASS
485549
rarity: COMMON
486550
components:
551+
- id: CUSTOM_DROP
552+
rules:
553+
# No silk touch = no drops
554+
- conditions:
555+
silk_touch: false
556+
drops: [ ]
557+
# Silk touch = get glass back
558+
- conditions:
559+
silk_touch: true
560+
drops:
561+
- item: GLASS
562+
chance: 1.0
563+
amount: 1
487564
- id: PLACEABLE
488565
- id: SELLABLE
489566
value: 3.0

configuration/settings.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ title:
9090
# Don't use secret if you not use MODERN type
9191
infoForwarding:
9292
type: MODERN
93-
secret: '9KfeURi1losL'
93+
secret: 'ixmSUgWOgvs7'
9494
tokens:
9595
- '<BUNGEE_GUARD_TOKEN>'
9696

loader/src/main/java/net/swofty/loader/SkyBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static void main(String[] args) {
5858
ServerType serverType = ServerType.valueOf(args[0].toUpperCase());
5959
long startTime = System.currentTimeMillis();
6060

61-
boolean isPterodactyl = Configuration.getOrDefault("pterodactyl-mode" , false);
61+
boolean isPterodactyl = Configuration.getOrDefault("pterodaddctyl-mode" , false);
6262

6363
if (isPterodactyl && args.length < 2) {
6464
Logger.error("Please specify server port.");

type.generic/src/main/java/net/swofty/types/generic/enchantment/EnchantmentType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public enum EnchantmentType {
2424
LOOTING(EnchantmentLooting.class),
2525
ENDER_SLAYER(EnchantmentEnderSlayer.class),
2626
SMITE(EnchantmentSmite.class),
27+
SILK_TOUCH(EnchantmentSilkTouch.class),
2728
;
2829

2930
private final Class<? extends Ench> clazz;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package net.swofty.types.generic.enchantment.impl;
2+
3+
import lombok.NonNull;
4+
import net.swofty.types.generic.collection.CustomCollectionAward;
5+
import net.swofty.types.generic.enchantment.abstr.Ench;
6+
import net.swofty.types.generic.enchantment.abstr.EnchFromTable;
7+
import net.swofty.types.generic.user.SkyBlockPlayer;
8+
import net.swofty.types.generic.utility.groups.EnchantItemGroups;
9+
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
public class EnchantmentSilkTouch implements Ench, EnchFromTable {
15+
16+
@Override
17+
public String getDescription(int level) {
18+
return "§7Allows you to mine blocks in their original form.";
19+
}
20+
21+
@Override
22+
public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) {
23+
HashMap<Integer, Integer> levels = new HashMap<>(Map.of(
24+
1, 64
25+
));
26+
return new ApplyLevels(levels);
27+
}
28+
29+
@Override
30+
public List<EnchantItemGroups> getGroups() {
31+
return List.of(
32+
EnchantItemGroups.PICKAXE,
33+
EnchantItemGroups.TOOLS
34+
);
35+
}
36+
37+
@Override
38+
public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) {
39+
HashMap<Integer, Integer> levels = new HashMap<>(Map.of(
40+
1, 30
41+
));
42+
return new TableLevels(levels);
43+
}
44+
45+
@Override
46+
public int getRequiredBookshelfPower() {
47+
return 15;
48+
}
49+
}

type.generic/src/main/java/net/swofty/types/generic/event/actions/player/gui/ActionPlayerInteractWithCrafting.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.swofty.types.generic.event.actions.player.gui;
22

33
import net.minestom.server.event.inventory.InventoryPreClickEvent;
4+
import net.minestom.server.inventory.PlayerInventory;
45
import net.minestom.server.inventory.click.ClickType;
56
import net.minestom.server.item.ItemStack;
67
import net.swofty.types.generic.event.EventNodes;
@@ -16,7 +17,7 @@ public class ActionPlayerInteractWithCrafting implements SkyBlockEventClass {
1617
public void run(InventoryPreClickEvent event) {
1718
SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer();
1819

19-
if (event.getInventory() != null) return;
20+
if (!(event.getInventory() instanceof PlayerInventory)) return;
2021
if (event.getSlot() < 37 || event.getSlot() > 40) return;
2122

2223
if (!event.getClickType().equals(ClickType.CHANGE_HELD)) // Fix dupe glitches by numkeying items into recipe grid

type.generic/src/main/java/net/swofty/types/generic/event/actions/player/region/ActionRegionBlockBreak.java

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import net.swofty.types.generic.event.EventNodes;
1212
import net.swofty.types.generic.event.SkyBlockEventClass;
1313
import net.swofty.types.generic.event.SkyBlockEventHandler;
14-
import net.swofty.types.generic.item.ItemDropChanger;
1514
import net.swofty.types.generic.item.SkyBlockItem;
15+
import net.swofty.types.generic.item.components.CustomDropComponent;
1616
import net.swofty.types.generic.region.RegionType;
1717
import net.swofty.types.generic.region.SkyBlockMiningConfiguration;
1818
import net.swofty.types.generic.region.SkyBlockRegion;
@@ -21,6 +21,8 @@
2121
import net.swofty.types.generic.event.SkyBlockEvent;
2222
import net.swofty.types.generic.event.custom.CustomBlockBreakEvent;
2323

24+
import java.util.List;
25+
2426
public class ActionRegionBlockBreak implements SkyBlockEventClass {
2527

2628
@SkyBlockEvent(node = EventNodes.PLAYER, requireDataLoaded = false)
@@ -68,74 +70,85 @@ else if (region != null) {
6870

6971
// Handle item drops for valid breaks
7072
if (material != null && shouldItemDrop) {
71-
// Determine which item should be dropped
72-
SkyBlockItem item = ItemDropChanger.get(material) != null ?
73-
ItemDropChanger.get(material).getItemSupplier().get() :
74-
new SkyBlockItem(material);
73+
SkyBlockItem brokenBlockItem = new SkyBlockItem(material);
74+
75+
// Determine which item(s) should be dropped using CustomDropComponent
76+
List<SkyBlockItem> customDrops = CustomDropComponent.simulateDrop(
77+
brokenBlockItem,
78+
player,
79+
new SkyBlockItem(player.getItemInMainHand()),
80+
region,
81+
SkyBlockConst.isIslandServer()
82+
);
7583

7684
// Call custom break event
7785
SkyBlockEventHandler.callSkyBlockEvent(new CustomBlockBreakEvent(
78-
player, item.getMaterial(), event.getBlockPosition()
86+
player, material, event.getBlockPosition(), customDrops
7987
));
8088

81-
// Calculate drop amount with fortune multiplier
82-
int dropAmount;
83-
try {
84-
MineableBlock mineableBlock = MineableBlock.get(block);
85-
double baseFortune = player.getStatistics().allStatistics().getOverall(mineableBlock.getBlockType().baseSkillFortune()); //might need to return 100 if null
86-
double specificFortune = player.getStatistics().allStatistics().getOverall(mineableBlock.getBlockType().specificBlockFortune());
87-
double fortune = baseFortune + specificFortune;
88-
double dropMultiplicator = (1 + (fortune * 0.01));
89-
dropAmount = mineableBlock.getDrops().getAmount(dropMultiplicator);
90-
} catch (NullPointerException e) {
91-
dropAmount = 1;
92-
}
89+
// Process each drop with fortune multiplier
90+
for (SkyBlockItem dropItem : customDrops) {
91+
// Calculate drop amount with fortune multiplier
92+
int dropAmount = dropItem.getAmount(); // Base amount from CustomDropComponent
93+
94+
try {
95+
MineableBlock mineableBlock = MineableBlock.get(block);
96+
if (mineableBlock != null) {
97+
double baseFortune = player.getStatistics().allStatistics().getOverall(mineableBlock.getBlockType().baseSkillFortune());
98+
double specificFortune = player.getStatistics().allStatistics().getOverall(mineableBlock.getBlockType().specificBlockFortune());
99+
double fortune = baseFortune + specificFortune;
100+
double dropMultiplier = (1 + (fortune * 0.01));
101+
dropAmount = (int) Math.ceil(dropAmount * dropMultiplier);
102+
}
103+
} catch (NullPointerException e) {
104+
// Keep base amount if fortune calculation fails
105+
}
93106

94-
// Create the item to be given to the player
95-
SkyBlockItem skyBlockItem = new SkyBlockItem(item.getItemStackBuilder().amount(dropAmount).build());
96-
ItemType droppedItemType = skyBlockItem.getAttributeHandler().getPotentialType();
97-
98-
// Handle item distribution based on player conditions
99-
if (player.canInsertItemIntoSacks(droppedItemType, dropAmount)) {
100-
player.getSackItems().increase(droppedItemType, dropAmount);
101-
} else if (player.getSkyBlockExperience().getLevel().asInt() >= 6) {
102-
player.addAndUpdateItem(skyBlockItem);
103-
} else {
104-
// Determine nearest air block between ore and player
105-
Pos orePos = Pos.fromPoint(event.getBlockPosition());
106-
Pos playerPos = player.getPosition();
107-
108-
Pos[] offsets = {
109-
new Pos(1, 0, 0), new Pos(-1, 0, 0),
110-
new Pos(0, 1, 0), new Pos(0, -1, 0),
111-
new Pos(0, 0, 1), new Pos(0, 0, -1)
112-
};
113-
114-
Pos nearestAirBlock = null;
115-
double closestDistanceSquared = Double.MAX_VALUE;
116-
117-
for (Pos offset : offsets) {
118-
Pos adjacentPos = orePos.add(offset);
119-
Block block2 = player.getInstance().getBlock(adjacentPos);
120-
121-
if (block2.isAir()) {
122-
double distanceSquared = adjacentPos.distanceSquared(playerPos);
123-
if (distanceSquared < closestDistanceSquared) {
124-
closestDistanceSquared = distanceSquared;
125-
nearestAirBlock = adjacentPos;
107+
// Update the drop item amount
108+
dropItem.setAmount(dropAmount);
109+
ItemType droppedItemType = dropItem.getAttributeHandler().getPotentialType();
110+
111+
// Handle item distribution based on player conditions
112+
if (player.canInsertItemIntoSacks(droppedItemType, dropAmount)) {
113+
player.getSackItems().increase(droppedItemType, dropAmount);
114+
} else if (player.getSkyBlockExperience().getLevel().asInt() >= 6) {
115+
player.addAndUpdateItem(dropItem);
116+
} else {
117+
// Determine nearest air block between ore and player
118+
Pos orePos = Pos.fromPoint(event.getBlockPosition());
119+
Pos playerPos = player.getPosition();
120+
121+
Pos[] offsets = {
122+
new Pos(1, 0, 0), new Pos(-1, 0, 0),
123+
new Pos(0, 1, 0), new Pos(0, -1, 0),
124+
new Pos(0, 0, 1), new Pos(0, 0, -1)
125+
};
126+
127+
Pos nearestAirBlock = null;
128+
double closestDistanceSquared = Double.MAX_VALUE;
129+
130+
for (Pos offset : offsets) {
131+
Pos adjacentPos = orePos.add(offset);
132+
Block block2 = player.getInstance().getBlock(adjacentPos);
133+
134+
if (block2.isAir()) {
135+
double distanceSquared = adjacentPos.distanceSquared(playerPos);
136+
if (distanceSquared < closestDistanceSquared) {
137+
closestDistanceSquared = distanceSquared;
138+
nearestAirBlock = adjacentPos;
139+
}
126140
}
127141
}
128-
}
129142

130-
// Use the nearest air block or fallback to default position
131-
Pos dropPos = (nearestAirBlock != null) ? nearestAirBlock.add(0.5, 0.5, 0.5) : orePos.add(0.5, 1.5, 0.5);
143+
// Use the nearest air block or fallback to default position
144+
Pos dropPos = (nearestAirBlock != null) ? nearestAirBlock.add(0.5, 0.5, 0.5) : orePos.add(0.5, 1.5, 0.5);
132145

133-
// Spawn the item
134-
DroppedItemEntityImpl droppedItem = new DroppedItemEntityImpl(skyBlockItem, player);
135-
droppedItem.setInstance(player.getInstance(), dropPos);
136-
droppedItem.addViewer(player);
146+
// Spawn the item
147+
DroppedItemEntityImpl droppedItem = new DroppedItemEntityImpl(dropItem, player);
148+
droppedItem.setInstance(player.getInstance(), dropPos);
149+
droppedItem.addViewer(player);
150+
}
137151
}
138-
139152
}
140153
}
141154
}

0 commit comments

Comments
 (0)