Compare commits

...

15 Commits

Author SHA1 Message Date
Timon Michel 3b783bd595
Merge 988d8beba5 into 77414a8172 2024-04-04 00:51:52 +08:00
BuildTools 77414a8172 v4.0.3 beta 2024-04-03 21:29:47 +05:00
BuildTools 79812ec42b v4.0.2 beta 2024-04-03 16:03:06 +05:00
EinDev 988d8beba5 Update dependency for gh actions 2024-03-25 20:17:09 +01:00
EinDev 487dc9e848 Update dependency for gh actions 2024-03-25 20:12:26 +01:00
Timon Michel b321b7710b
Merge branch 'master' into add-github-actions 2024-03-25 18:38:43 +01:00
EinDev 8eb2432bf8 Oops, how did that get here? 2023-12-29 22:39:29 +01:00
EinDev a8b0dcb324 Remove not yet supported version 2023-12-29 22:35:48 +01:00
EinDev 1f9b290faf Fix dumb substitution typo 2023-12-29 22:27:10 +01:00
EinDev 20ff3f2f1a Add a ci matrix 2023-12-29 22:24:42 +01:00
EinDev 60cd01ea1c Add artifact upload 2023-12-29 21:17:14 +01:00
EinDev 950c35eb97 Fix typo 2023-12-29 21:01:46 +01:00
EinDev 56cd9a0468 Add additional comments 2023-12-29 20:47:36 +01:00
EinDev 0cb6a84e5e Fix Typo 2023-12-29 20:45:28 +01:00
EinDev 188b13ba1a [WIP] Add GitHub Action build workflow 2023-12-29 20:43:45 +01:00
24 changed files with 580 additions and 56 deletions

133
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,133 @@
---
name: Build the plugin
on: [ push ]
jobs:
install-dependencies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache maven repository
id: cache-mvn
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-maven
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
- name: Install Spigot 1.20.4
uses: SpraxDev/Action-SpigotMC@v4
with:
versions: 1.20.4
remapped: true
buildToolProvider: SpigotMC
- name: Install Spigot 1.20.2
uses: SpraxDev/Action-SpigotMC@v4
with:
versions: 1.20.2
remapped: true
buildToolProvider: SpigotMC
- name: Install Spigot 1.20.1
uses: SpraxDev/Action-SpigotMC@v4
with:
versions: 1.20.1
remapped: true
buildToolProvider: SpigotMC
- name: Install Spigot 1.19.4
uses: SpraxDev/Action-SpigotMC@v4
with:
versions: 1.19.4
remapped: true
buildToolProvider: SpigotMC
- name: Install Spigot 1.18.2
uses: SpraxDev/Action-SpigotMC@v4
with:
versions: 1.18.2
remapped: true
buildToolProvider: SpigotMC
- name: Check out nightcore
uses: actions/checkout@v4
with:
repository: 'nulli0n/nightcore-spigot'
ref: 'f70589cbe2b2fde92a1941e76a408dc1296490c5'
path: 'nightcore'
- name: Install nightcore
run: mvn install
working-directory: ./nightcore
ci:
runs-on: ubuntu-latest
needs: [ install-dependencies ]
strategy:
matrix:
spigot:
- 1.20.2-R0.1-SNAPSHOT
- 1.20.1-R0.1-SNAPSHOT
- 1.19.4-R0.1-SNAPSHOT
- 1.18.2-R0.1-SNAPSHOT
steps:
- uses: actions/checkout@v4
- name: Cache maven repository
id: cache-mvn
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-maven
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
- name: Package plugin
run: mvn package -Dspigot.version=${{ matrix.spigot }}
build:
runs-on: ubuntu-latest
needs: [ install-dependencies ]
steps:
- uses: actions/checkout@v4
- name: Cache maven repository
id: cache-mvn
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-maven
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
- name: Package plugin
run: mvn package
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ExcellentEnchants
path: target/*.jar

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,21 @@
package su.nightexpress.excellentenchants.api;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
public class EnchantingBridge {
private static ItemStack enchantingItem;
public static ItemStack getEnchantingItem() {
return enchantingItem;
}
public static void setEnchantingItem(@Nullable ItemStack itemStack) {
enchantingItem = itemStack;
}
public static void clear() {
enchantingItem = null;
}
}

View File

@ -32,10 +32,16 @@ public interface EnchantmentData {
boolean isAvailableToUse(@NotNull World world);
boolean checkEnchantLimit(@NotNull ItemStack item);
boolean checkEnchantCategory(@NotNull ItemStack item);
boolean checkItemCategory(@NotNull ItemStack item);
default boolean hasItemCategory() {
return this.getItemCategories().length != 0;
}
@NotNull DistributionOptions getDistributionOptions();
@NotNull Rarity getRarity();

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -15,6 +15,7 @@
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
</properties>
<repositories>
@ -44,7 +45,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<version>${spigot.version}</version>
</dependency>
<dependency>
<groupId>fr.neatmonster</groupId>
@ -73,32 +74,32 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_19_R3</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R1</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R2</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>V1_20_R3</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -51,6 +51,11 @@ public class Config {
"[Default is true]"
);
public static final ConfigValue<Integer> CORE_ITEM_ENCHANT_LIMIT = ConfigValue.create("Core.Item_Enchantments_Limit",
3,
"Sets max. amount of custom enchantments per item.",
"[Default is 3]");
public static final ConfigValue<Boolean> CORE_SWORD_ENCHANTS_TO_AXES = ConfigValue.create("Core.Sword_Enchants_To_Axes",
true,
"Sets whether or not Sword enchantments can be applied on Axes.",

View File

@ -11,6 +11,7 @@ import su.nightexpress.excellentenchants.enchantment.impl.armor.FlameWalkerEncha
import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantGenericListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantPopulationListener;
import su.nightexpress.excellentenchants.enchantment.listener.EnchantVanillaListener;
import su.nightexpress.excellentenchants.enchantment.menu.EnchantmentsListMenu;
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
@ -44,9 +45,13 @@ public class EnchantManager extends AbstractManager<EnchantsPlugin> {
this.addListener(new EnchantAnvilListener(this.plugin));
if (Config.isCustomDistribution()) {
this.plugin.info("Using custom distribution system...");
this.plugin.info("Using custom distribution system. Applying patches...");
this.addListener(new EnchantPopulationListener(this.plugin));
}
else {
this.plugin.info("Using vanilla distribution. Applying enchanting table patches...");
this.addListener(new EnchantVanillaListener(this.plugin));
}
this.addTask(this.plugin.createAsyncTask(this::displayProjectileTrails).setTicksInterval(Config.CORE_PROJECTILE_PARTICLE_INTERVAL.get()));
this.addTask(this.plugin.createTask(this::updatePassiveEnchantEffects).setTicksInterval(Config.CORE_PASSIVE_ENCHANTS_TRIGGER_INTERVAL.get()));

View File

@ -160,10 +160,11 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
//int costAdjust = Math.max(7, 42 - this.getMaxLevel() * 7);
double costBase = Config.isVanillaDistribution() ? 45D : 30D;
double costMaxBase = Config.isVanillaDistribution() ? Rnd.get(6, 8) : 0;
double costAdjust = costBase / this.getMaxLevel();
this.setMinCost(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Min_Cost",
Modifier.add(1 - costAdjust, costAdjust, 1),
Modifier.add(1 - costAdjust, costAdjust - 1, 1),
VANILLA_DISTRIBUTION_HEADER,
"Sets min. **modified** level cost for this enchantment to be selected in enchanting table.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
@ -173,7 +174,7 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
);
this.setMaxCost(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Max_Cost",
Modifier.add(12 - costAdjust, costAdjust, 1),
Modifier.add(costMaxBase, costAdjust, 1),
VANILLA_DISTRIBUTION_HEADER,
"Sets max. **modified** level cost for this enchantment to be selected in enchanting table.",
"Explanation: https://minecraft.wiki/w/Enchanting_mechanics#How_enchantments_are_chosen",
@ -342,6 +343,14 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
return this.isAvailableToUse(entity.getWorld());
}
@Override
public boolean checkEnchantLimit(@NotNull ItemStack item) {
int limit = Config.CORE_ITEM_ENCHANT_LIMIT.get();
int has = EnchantUtils.countCustomEnchantments(item);
return has < limit;
}
@Override
public final boolean checkEnchantCategory(@NotNull ItemStack item) {
EnchantmentTarget category = this.getCategory();
@ -360,10 +369,7 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
@Override
public boolean checkItemCategory(@NotNull ItemStack item) {
ItemCategory[] itemCategories = this.getItemCategories();
if (itemCategories.length == 0) return false;
return Stream.of(itemCategories).anyMatch(itemCategory -> itemCategory.isIncluded(item));
return !this.hasItemCategory() || Stream.of(this.getItemCategories()).anyMatch(itemCategory -> itemCategory.isIncluded(item));
}
public int generateLevel() {

View File

@ -0,0 +1,90 @@
package su.nightexpress.excellentenchants.enchantment.listener;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.EnchantsPlugin;
import su.nightexpress.excellentenchants.api.EnchantingBridge;
import su.nightexpress.nightcore.manager.AbstractListener;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class EnchantVanillaListener extends AbstractListener<EnchantsPlugin> {
private final Map<UUID, Map<Integer, Map<Enchantment, Integer>>> finedEnchants;
public EnchantVanillaListener(@NotNull EnchantsPlugin plugin) {
super(plugin);
this.finedEnchants = new HashMap<>();
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent event) {
this.finedEnchants.remove(event.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEnchantTableBridgePurge(InventoryCloseEvent event) {
Inventory inventory = event.getInventory();
if (inventory.getType() != InventoryType.ENCHANTING) return;
this.finedEnchants.remove(event.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onEnchantTableBridgeSet(InventoryClickEvent event) {
Inventory inventory = event.getInventory();
if (inventory.getType() != InventoryType.ENCHANTING) return;
// I don't know if Mojang is stupid or something
// they use "enchantment.category.canEnchant(item) instead of enchantment.canEnchant(item)
// which fuck ups all custom changes in that overridden method.
// Problem here: EnchantingMenu -> getEnchantmentList -> EnchantmentHelper.selectEnchantment -> getAvailableEnchantmentResults
// We store enchanting item in EnchantingBridge and adjust custom enchantment's 'isDiscoverable' result depends on the item.
// Then only proper enchantments will appear from 'getEnchantsList' method of EnchantmentMenu.
// We store them in a map here and change offers in NMS for best visual result.
// In EnchantItemEven prepared enchantments are used to replace the result.
this.plugin.runTask(task -> {
Player player = (Player) event.getWhoClicked();
ItemStack target = inventory.getItem(0);
EnchantingBridge.setEnchantingItem(target);
if (target != null) {
Map<Integer, Map<Enchantment, Integer>> map = plugin.getEnchantNMS().getEnchantLists(inventory, target);
this.finedEnchants.put(player.getUniqueId(), map);
EnchantingBridge.clear();
}
else {
this.finedEnchants.remove(player.getUniqueId());
}
});
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onEnchantTableFixResult(EnchantItemEvent event) {
Player player = event.getEnchanter();
int button = event.whichButton();
Map<Integer, Map<Enchantment, Integer>> indexMap = this.finedEnchants.remove(player.getUniqueId());
if (indexMap == null) return;
Map<Enchantment, Integer> enchantmentMap = indexMap.get(button);
if (enchantmentMap == null) return;
event.getEnchantsToAdd().clear();
event.getEnchantsToAdd().putAll(enchantmentMap);
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -33,7 +33,7 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -3,14 +3,17 @@ package su.nightexpress.excellentenchants.nms;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import java.util.Map;
import java.util.Set;
public interface EnchantNMS {
@ -25,6 +28,8 @@ public interface EnchantNMS {
void retrieveHook(@NotNull FishHook hook, @NotNull ItemStack item);
@NotNull Map<Integer, Map<Enchantment, Integer>> getEnchantLists(@NotNull Inventory inventory, @NotNull ItemStack bukkitItem);
@NotNull Material getItemBlockVariant(@NotNull Material material);
@NotNull Set<Block> handleFlameWalker(@NotNull LivingEntity entity, @NotNull Location location, int level);

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -27,7 +27,7 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -11,6 +11,7 @@ import org.bukkit.craftbukkit.v1_19_R3.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_19_R3.util.CraftNamespacedKey;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.EnchantingBridge;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
@ -66,11 +67,19 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean canEnchant(ItemStack item) {
org.bukkit.inventory.ItemStack bukkitStack = CraftItemStack.asBukkitCopy(item);
if (this.enchantmentData.checkEnchantCategory(bukkitStack)) return true;
if (this.enchantmentData.checkItemCategory(bukkitStack)) return true;
if (!super.canEnchant(item)) return false;
return super.canEnchant(item);
return this.canEnchant(CraftItemStack.asBukkitCopy(item));
}
public boolean canEnchant(@NotNull org.bukkit.inventory.ItemStack bukkitItem) {
if (!this.enchantmentData.checkEnchantLimit(bukkitItem)) return false;
if (!this.enchantmentData.hasItemCategory()) {
if (this.enchantmentData.checkEnchantCategory(bukkitItem)) return true;
}
return this.enchantmentData.checkItemCategory(bukkitItem);
}
@Override
@ -90,6 +99,11 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean isDiscoverable() {
org.bukkit.inventory.ItemStack bukkitItem = EnchantingBridge.getEnchantingItem();
if (bukkitItem != null && !this.canEnchant(bukkitItem)) {
return false;
}
return this.vanillaOptions != null && this.vanillaOptions.isDiscoverable();
}

View File

@ -4,13 +4,17 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -26,22 +30,26 @@ import org.bukkit.craftbukkit.v1_19_R3.entity.CraftFishHook;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R3.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_19_R3.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Reflex;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set;
import java.lang.reflect.Method;
import java.util.*;
public class V1_19_R3 implements EnchantNMS {
@ -69,6 +77,47 @@ public class V1_19_R3 implements EnchantNMS {
data.setEnchantment(craftEnchantment);
}
private static final Method GET_ENCHANTS_LIST = Reflex.getMethod(EnchantmentMenu.class, "a", net.minecraft.world.item.ItemStack.class, Integer.TYPE, Integer.TYPE);
@SuppressWarnings("unchecked")
@NotNull
@Override
public Map<Integer, Map<Enchantment, Integer>> getEnchantLists(@NotNull Inventory inventory, @NotNull ItemStack bukkitItem) {
Map<Integer, Map<Enchantment, Integer>> map = new HashMap<>();
// Returns SimpleContainer class assigned to 'enchantSlots' field.
Container container = ((CraftInventory) inventory).getInventory();
// Get parent (real EnchantmentMenu) object from SimpleContainer obtained above.
EnchantmentMenu enchantmentMenu = (EnchantmentMenu) Reflex.getFieldValue(container, "this$0");
net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
for (int button = 0; button < 3; button++) {
int cost = enchantmentMenu.costs[button];
List<EnchantmentInstance> list = (List<EnchantmentInstance>) Reflex.invokeMethod(GET_ENCHANTS_LIST, enchantmentMenu, itemStack, button, cost);
Map<Enchantment, Integer> enchantments = new HashMap<>();
if (list != null && !list.isEmpty()) {
EnchantmentInstance random = Rnd.get(list);
enchantmentMenu.enchantClue[button] = BuiltInRegistries.ENCHANTMENT.getId(random.enchantment);
enchantmentMenu.levelClue[button] = random.level;
for (EnchantmentInstance instance : list) {
ResourceLocation location = BuiltInRegistries.ENCHANTMENT.getKey(instance.enchantment);
if (location == null) continue;
enchantments.put(BukkitThing.getEnchantment(CraftNamespacedKey.fromMinecraft(location).getKey()), instance.level);
}
}
map.put(button, enchantments);
}
return map;
}
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -27,7 +27,7 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -11,6 +11,7 @@ import org.bukkit.craftbukkit.v1_20_R1.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R1.util.CraftNamespacedKey;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.EnchantingBridge;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
@ -66,11 +67,19 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean canEnchant(ItemStack item) {
org.bukkit.inventory.ItemStack bukkitStack = CraftItemStack.asBukkitCopy(item);
if (this.enchantmentData.checkEnchantCategory(bukkitStack)) return true;
if (this.enchantmentData.checkItemCategory(bukkitStack)) return true;
if (!super.canEnchant(item)) return false;
return super.canEnchant(item);
return this.canEnchant(CraftItemStack.asBukkitCopy(item));
}
public boolean canEnchant(@NotNull org.bukkit.inventory.ItemStack bukkitItem) {
if (!this.enchantmentData.checkEnchantLimit(bukkitItem)) return false;
if (!this.enchantmentData.hasItemCategory()) {
if (this.enchantmentData.checkEnchantCategory(bukkitItem)) return true;
}
return this.enchantmentData.checkItemCategory(bukkitItem);
}
@Override
@ -90,6 +99,11 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean isDiscoverable() {
org.bukkit.inventory.ItemStack bukkitItem = EnchantingBridge.getEnchantingItem();
if (bukkitItem != null && !this.canEnchant(bukkitItem)) {
return false;
}
return this.vanillaOptions != null && this.vanillaOptions.isDiscoverable();
}

View File

@ -4,14 +4,18 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -27,22 +31,26 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftFishHook;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R1.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Reflex;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set;
import java.lang.reflect.Method;
import java.util.*;
public class V1_20_R1 implements EnchantNMS {
@ -70,6 +78,47 @@ public class V1_20_R1 implements EnchantNMS {
data.setEnchantment(craftEnchantment);
}
private static final Method GET_ENCHANTS_LIST = Reflex.getMethod(EnchantmentMenu.class, "a", net.minecraft.world.item.ItemStack.class, Integer.TYPE, Integer.TYPE);
@SuppressWarnings("unchecked")
@NotNull
@Override
public Map<Integer, Map<Enchantment, Integer>> getEnchantLists(@NotNull Inventory inventory, @NotNull ItemStack bukkitItem) {
Map<Integer, Map<Enchantment, Integer>> map = new HashMap<>();
// Returns SimpleContainer class assigned to 'enchantSlots' field.
Container container = ((CraftInventory) inventory).getInventory();
// Get parent (real EnchantmentMenu) object from SimpleContainer obtained above.
EnchantmentMenu enchantmentMenu = (EnchantmentMenu) Reflex.getFieldValue(container, "this$0");
net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
for (int button = 0; button < 3; button++) {
int cost = enchantmentMenu.costs[button];
List<EnchantmentInstance> list = (List<EnchantmentInstance>) Reflex.invokeMethod(GET_ENCHANTS_LIST, enchantmentMenu, itemStack, button, cost);
Map<Enchantment, Integer> enchantments = new HashMap<>();
if (list != null && !list.isEmpty()) {
EnchantmentInstance random = Rnd.get(list);
enchantmentMenu.enchantClue[button] = BuiltInRegistries.ENCHANTMENT.getId(random.enchantment);
enchantmentMenu.levelClue[button] = random.level;
for (EnchantmentInstance instance : list) {
ResourceLocation location = BuiltInRegistries.ENCHANTMENT.getKey(instance.enchantment);
if (location == null) continue;
enchantments.put(BukkitThing.getEnchantment(CraftNamespacedKey.fromMinecraft(location).getKey()), instance.level);
}
}
map.put(button, enchantments);
}
return map;
}
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -27,7 +27,7 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -11,6 +11,7 @@ import org.bukkit.craftbukkit.v1_20_R2.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.EnchantingBridge;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
@ -66,11 +67,19 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean canEnchant(ItemStack item) {
org.bukkit.inventory.ItemStack bukkitStack = CraftItemStack.asBukkitCopy(item);
if (this.enchantmentData.checkEnchantCategory(bukkitStack)) return true;
if (this.enchantmentData.checkItemCategory(bukkitStack)) return true;
if (!super.canEnchant(item)) return false;
return super.canEnchant(item);
return this.canEnchant(CraftItemStack.asBukkitCopy(item));
}
public boolean canEnchant(@NotNull org.bukkit.inventory.ItemStack bukkitItem) {
if (!this.enchantmentData.checkEnchantLimit(bukkitItem)) return false;
if (!this.enchantmentData.hasItemCategory()) {
if (this.enchantmentData.checkEnchantCategory(bukkitItem)) return true;
}
return this.enchantmentData.checkItemCategory(bukkitItem);
}
@Override
@ -90,6 +99,11 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean isDiscoverable() {
org.bukkit.inventory.ItemStack bukkitItem = EnchantingBridge.getEnchantingItem();
if (bukkitItem != null && !this.canEnchant(bukkitItem)) {
return false;
}
return this.vanillaOptions != null && this.vanillaOptions.isDiscoverable();
}

View File

@ -4,14 +4,18 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -27,22 +31,26 @@ import org.bukkit.craftbukkit.v1_20_R2.entity.CraftFishHook;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R2.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Reflex;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set;
import java.lang.reflect.Method;
import java.util.*;
public class V1_20_R2 implements EnchantNMS {
@ -69,6 +77,47 @@ public class V1_20_R2 implements EnchantNMS {
data.setEnchantment(craftEnchantment);
}
private static final Method GET_ENCHANTS_LIST = Reflex.getMethod(EnchantmentMenu.class, "a", net.minecraft.world.item.ItemStack.class, Integer.TYPE, Integer.TYPE);
@SuppressWarnings("unchecked")
@NotNull
@Override
public Map<Integer, Map<Enchantment, Integer>> getEnchantLists(@NotNull Inventory inventory, @NotNull ItemStack bukkitItem) {
Map<Integer, Map<Enchantment, Integer>> map = new HashMap<>();
// Returns SimpleContainer class assigned to 'enchantSlots' field.
Container container = ((CraftInventory) inventory).getInventory();
// Get parent (real EnchantmentMenu) object from SimpleContainer obtained above.
EnchantmentMenu enchantmentMenu = (EnchantmentMenu) Reflex.getFieldValue(container, "this$0");
net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
for (int button = 0; button < 3; button++) {
int cost = enchantmentMenu.costs[button];
List<EnchantmentInstance> list = (List<EnchantmentInstance>) Reflex.invokeMethod(GET_ENCHANTS_LIST, enchantmentMenu, itemStack, button, cost);
Map<Enchantment, Integer> enchantments = new HashMap<>();
if (list != null && !list.isEmpty()) {
EnchantmentInstance random = Rnd.get(list);
enchantmentMenu.enchantClue[button] = BuiltInRegistries.ENCHANTMENT.getId(random.enchantment);
enchantmentMenu.levelClue[button] = random.level;
for (EnchantmentInstance instance : list) {
ResourceLocation location = BuiltInRegistries.ENCHANTMENT.getKey(instance.enchantment);
if (location == null) continue;
enchantments.put(BukkitThing.getEnchantment(CraftNamespacedKey.fromMinecraft(location).getKey()), instance.level);
}
}
map.put(button, enchantments);
}
return map;
}
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ExcellentEnchants</artifactId>
<groupId>su.nightexpress.excellentenchants</groupId>
<version>4.0.1</version>
<version>4.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -27,12 +27,12 @@
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>API</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>NMS</artifactId>
<version>4.0.1</version>
<version>4.0.3</version>
</dependency>
</dependencies>

View File

@ -11,6 +11,7 @@ import org.bukkit.craftbukkit.v1_20_R3.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.EnchantingBridge;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
@ -66,11 +67,19 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean canEnchant(ItemStack item) {
org.bukkit.inventory.ItemStack bukkitStack = CraftItemStack.asBukkitCopy(item);
if (this.enchantmentData.checkEnchantCategory(bukkitStack)) return true;
if (this.enchantmentData.checkItemCategory(bukkitStack)) return true;
if (!super.canEnchant(item)) return false;
return super.canEnchant(item);
return this.canEnchant(CraftItemStack.asBukkitCopy(item));
}
public boolean canEnchant(@NotNull org.bukkit.inventory.ItemStack bukkitItem) {
if (!this.enchantmentData.checkEnchantLimit(bukkitItem)) return false;
if (!this.enchantmentData.hasItemCategory()) {
if (this.enchantmentData.checkEnchantCategory(bukkitItem)) return true;
}
return this.enchantmentData.checkItemCategory(bukkitItem);
}
@Override
@ -90,6 +99,11 @@ public class CustomEnchantment extends Enchantment {
@Override
public boolean isDiscoverable() {
org.bukkit.inventory.ItemStack bukkitItem = EnchantingBridge.getEnchantingItem();
if (bukkitItem != null && !this.canEnchant(bukkitItem)) {
return false;
}
return this.vanillaOptions != null && this.vanillaOptions.isDiscoverable();
}

View File

@ -4,14 +4,18 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.FishingHook;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
@ -28,21 +32,25 @@ import org.bukkit.craftbukkit.v1_20_R3.entity.CraftFishHook;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R3.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
import su.nightexpress.excellentenchants.nms.EnchantNMS;
import su.nightexpress.nightcore.util.BukkitThing;
import su.nightexpress.nightcore.util.Reflex;
import su.nightexpress.nightcore.util.random.Rnd;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set;
import java.lang.reflect.Method;
import java.util.*;
public class V1_20_R3 implements EnchantNMS {
@ -65,6 +73,47 @@ public class V1_20_R3 implements EnchantNMS {
data.setEnchantment(bukkitEnchant);
}
private static final Method GET_ENCHANTS_LIST = Reflex.getMethod(EnchantmentMenu.class, "a", net.minecraft.world.item.ItemStack.class, Integer.TYPE, Integer.TYPE);
@SuppressWarnings("unchecked")
@NotNull
@Override
public Map<Integer, Map<Enchantment, Integer>> getEnchantLists(@NotNull Inventory inventory, @NotNull ItemStack bukkitItem) {
Map<Integer, Map<Enchantment, Integer>> map = new HashMap<>();
// Returns SimpleContainer class assigned to 'enchantSlots' field.
Container container = ((CraftInventory) inventory).getInventory();
// Get parent (real EnchantmentMenu) object from SimpleContainer obtained above.
EnchantmentMenu enchantmentMenu = (EnchantmentMenu) Reflex.getFieldValue(container, "this$0");
net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
for (int button = 0; button < 3; button++) {
int cost = enchantmentMenu.costs[button];
List<EnchantmentInstance> list = (List<EnchantmentInstance>) Reflex.invokeMethod(GET_ENCHANTS_LIST, enchantmentMenu, itemStack, button, cost);
Map<Enchantment, Integer> enchantments = new HashMap<>();
if (list != null && !list.isEmpty()) {
EnchantmentInstance random = Rnd.get(list);
enchantmentMenu.enchantClue[button] = BuiltInRegistries.ENCHANTMENT.getId(random.enchantment);
enchantmentMenu.levelClue[button] = random.level;
for (EnchantmentInstance instance : list) {
ResourceLocation location = BuiltInRegistries.ENCHANTMENT.getKey(instance.enchantment);
if (location == null) continue;
enchantments.put(BukkitThing.getEnchantment(CraftNamespacedKey.fromMinecraft(location).getKey()), instance.level);
}
}
map.put(button, enchantments);
}
return map;
}
@Override
public void sendAttackPacket(@NotNull Player player, int id) {
CraftPlayer craftPlayer = (CraftPlayer) player;

View File

@ -7,7 +7,7 @@
<groupId>su.nightexpress.excellentenchants</groupId>
<artifactId>ExcellentEnchants</artifactId>
<packaging>pom</packaging>
<version>4.0.1</version>
<version>4.0.3</version>
<modules>
<module>Core</module>
<module>NMS</module>