mirror of
https://github.com/nulli0n/ExcellentEnchants-spigot.git
synced 2024-11-22 11:35:18 +01:00
v4.0.5
This commit is contained in:
parent
5cfdf14198
commit
359782ff57
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,3 +17,5 @@
|
||||
/V1_20_R3/pom.xml.versionsBackup
|
||||
/API/target/
|
||||
/API/pom.xml.versionsBackup
|
||||
/MC_1_20_6/target/
|
||||
/MC_1_20_6/pom.xml.versionsBackup
|
@ -5,15 +5,16 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>API</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,51 @@
|
||||
package su.nightexpress.excellentenchants.api.enchantment;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
|
||||
public class Cost {
|
||||
|
||||
private final int base;
|
||||
private final int perLevel;
|
||||
|
||||
public Cost(int base, int perLevel) {
|
||||
this.base = base;
|
||||
this.perLevel = perLevel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Cost read(@NotNull FileConfig config, @NotNull String path, @NotNull Cost defaultValue, String ... comments) {
|
||||
return ConfigValue.create(path,
|
||||
(cfg2, path2, def2) -> Cost.read(cfg2, path2),
|
||||
(cfg2, path2, mod) -> mod.write(cfg2, path2),
|
||||
() -> defaultValue,
|
||||
comments
|
||||
).read(config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Cost read(@NotNull FileConfig config, @NotNull String path) {
|
||||
int base = ConfigValue.create(path + ".Base", 0).read(config);
|
||||
int perLevel = ConfigValue.create(path + ".Per_Level", 0).read(config);
|
||||
|
||||
return new Cost(base, perLevel);
|
||||
}
|
||||
|
||||
public void write(@NotNull FileConfig config, @NotNull String path) {
|
||||
config.set(path + ".Base", this.base());
|
||||
config.set(path + ".Per_Level", this.perLevel());
|
||||
}
|
||||
|
||||
public int calculate(int level) {
|
||||
return this.base + this.perLevel * (level - 1);
|
||||
}
|
||||
|
||||
public int base() {
|
||||
return this.base;
|
||||
}
|
||||
|
||||
public int perLevel() {
|
||||
return this.perLevel;
|
||||
}
|
||||
}
|
@ -20,6 +20,10 @@ import java.util.Set;
|
||||
|
||||
public interface EnchantmentData {
|
||||
|
||||
default void clear() {
|
||||
|
||||
}
|
||||
|
||||
@NotNull PlaceholderMap getPlaceholders(int level);
|
||||
|
||||
@NotNull FileConfig getConfig();
|
||||
@ -81,14 +85,8 @@ public interface EnchantmentData {
|
||||
|
||||
@NotNull Set<String> getConflicts();
|
||||
|
||||
int getMinLevel();
|
||||
|
||||
int getMaxLevel();
|
||||
|
||||
//int getMaxMergeLevel();
|
||||
|
||||
//int getAnvilMergeCost(int level);
|
||||
|
||||
int getMinCost(int level);
|
||||
|
||||
int getMaxCost(int level);
|
||||
@ -153,23 +151,19 @@ public interface EnchantmentData {
|
||||
|
||||
void setTreasure(boolean treasure);
|
||||
|
||||
void setStartLevel(int levelMin);
|
||||
|
||||
void setMaxLevel(int levelMax);
|
||||
|
||||
//void setMaxMergeLevel(int maxMergeLevel);
|
||||
@NotNull Cost getMinCost();
|
||||
|
||||
@NotNull Modifier getMinCost();
|
||||
void setMinCost(@NotNull Cost minCost);
|
||||
|
||||
void setMinCost(@NotNull Modifier minCost);
|
||||
@NotNull Cost getMaxCost();
|
||||
|
||||
@NotNull Modifier getMaxCost();
|
||||
void setMaxCost(@NotNull Cost maxCost);
|
||||
|
||||
void setMaxCost(@NotNull Modifier maxCost);
|
||||
int getAnvilCost();
|
||||
|
||||
//@NotNull Modifier getAnvilMergeCost();
|
||||
|
||||
//void setAnvilMergeCost(@NotNull Modifier anvilMergeCost);
|
||||
void setAnvilCost(int anvilCost);
|
||||
|
||||
default void setConflicts(@NotNull String... conflicts) {
|
||||
this.setConflicts(Lists.newSet(conflicts));
|
||||
|
23
Core/pom.xml
23
Core/pom.xml
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>Core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -67,32 +67,37 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>MC_1_20_6</artifactId>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R3</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R2</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_20_R1</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>V1_19_R3</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -110,6 +110,7 @@ public class EnchantsPlugin extends NightPlugin {
|
||||
case V1_20_R1 -> new V1_20_R1();
|
||||
case V1_20_R2 -> new V1_20_R2();
|
||||
case V1_20_R3 -> new V1_20_R3();
|
||||
case MC_1_20_6 -> new Internal1_20_6();
|
||||
default -> null;
|
||||
};
|
||||
return this.enchantNMS != null;
|
||||
|
@ -7,9 +7,9 @@ import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.config.Perms;
|
||||
import su.nightexpress.excellentenchants.Placeholders;
|
||||
import su.nightexpress.excellentenchants.config.Lang;
|
||||
import su.nightexpress.excellentenchants.config.Perms;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.command.CommandResult;
|
||||
import su.nightexpress.nightcore.command.impl.AbstractCommand;
|
||||
|
@ -75,7 +75,7 @@ public class RarityBookCommand extends AbstractCommand<EnchantsPlugin> {
|
||||
|
||||
int level = result.getInt(3, -1);
|
||||
if (level < 1) {
|
||||
level = Rnd.get(enchantmentData.getMinLevel(), enchantmentData.getMaxLevel());
|
||||
level = Rnd.get(1, enchantmentData.getMaxLevel());
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
|
||||
|
@ -60,12 +60,13 @@ public class EnchantManager extends AbstractManager<EnchantsPlugin> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown() {
|
||||
if (this.enchantmentsListMenu != null) this.enchantmentsListMenu.clear();
|
||||
|
||||
if (EnchantRegistry.isRegistered(FlameWalkerEnchant.ID)) {
|
||||
/*if (EnchantRegistry.isRegistered(FlameWalkerEnchant.ID)) {
|
||||
FlameWalkerEnchant.clear();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -215,7 +215,7 @@ public class EnchantPopulator {
|
||||
|
||||
// Level generation failed.
|
||||
int level = this.getLevelGenerator().apply(enchantmentData, distribution);
|
||||
if (level < enchantmentData.getMinLevel()) {
|
||||
if (level < 1) {
|
||||
this.purge(rarity, enchantmentData);
|
||||
continue;
|
||||
}
|
||||
|
@ -14,13 +14,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.DistributionWay;
|
||||
import su.nightexpress.excellentenchants.api.Modifier;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Cost;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.ItemCategory;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.ChanceData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.PeriodicData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.data.PotionData;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.distribution.DistributionOptions;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantPlaceholders;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
@ -56,13 +57,11 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
private boolean treasure;
|
||||
private boolean visualEffects;
|
||||
|
||||
private int minLevel;
|
||||
private int maxLevel;
|
||||
//private int maxMergeLevel;
|
||||
|
||||
private Modifier minCost;
|
||||
private Modifier maxCost;
|
||||
//private Modifier anvilMergeCost;
|
||||
private Cost minCost;
|
||||
private Cost maxCost;
|
||||
private int anvilCost;
|
||||
|
||||
private boolean chargesEnabled;
|
||||
private boolean chargesCustomFuel;
|
||||
@ -80,7 +79,6 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
super(plugin, file);
|
||||
this.setDescription(new ArrayList<>());
|
||||
this.setRarity(Rarity.COMMON);
|
||||
this.setStartLevel(1);
|
||||
this.setMaxLevel(3);
|
||||
|
||||
this.conflicts = new HashSet<>();
|
||||
@ -110,9 +108,12 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
protected boolean onLoad(@NotNull FileConfig cfg) {
|
||||
this.setRarity(ConfigValue.create("Settings.Rarity", Rarity.class, this.rarity,
|
||||
"The rarity is an attribute of an enchantment.",
|
||||
"It affects the chance of getting an enchantment from enchanting or loots as well as the combination cost in anvil."
|
||||
"It affects the chance of getting an enchantment from enchanting or loots as well as the combination cost in anvil.",
|
||||
"[*] Only for versions BELOW 1.20.6!"
|
||||
).read(cfg));
|
||||
|
||||
// TODO Custom rarity class for 1.21
|
||||
|
||||
this.setDisplayName(ConfigValue.create("Settings.Name",
|
||||
StringUtil.capitalizeUnderscored(this.getId()),
|
||||
"Enchantment name."
|
||||
@ -124,11 +125,6 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
"You can use 'Enchantment' placeholders: " + URL_PLACEHOLDERS
|
||||
).read(cfg));
|
||||
|
||||
this.setStartLevel(ConfigValue.create("Settings.Level.Min",
|
||||
this.getMinLevel(),
|
||||
"Min. enchantment level."
|
||||
).read(cfg));
|
||||
|
||||
this.setMaxLevel(ConfigValue.create("Settings.Level.Max",
|
||||
this.getMaxLevel(),
|
||||
"Max. enchantment level."
|
||||
@ -159,22 +155,24 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
).read(cfg));
|
||||
|
||||
//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();
|
||||
int costBase = Config.isVanillaDistribution() ? 45 : 30;
|
||||
int costStart = Rnd.get(5) + 1;
|
||||
int costMod = Rnd.get(10) + 1;
|
||||
int costPerLevel = (int) ((double) costBase / (double) this.getMaxLevel());
|
||||
|
||||
this.setMinCost(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Min_Cost",
|
||||
Modifier.add(1 - costAdjust, costAdjust - 1, 1),
|
||||
this.setMinCost(Cost.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Cost.Min",
|
||||
new Cost(costStart, costPerLevel),
|
||||
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",
|
||||
"Vanilla costs: https://minecraft.wiki/w/Enchanting/Levels",
|
||||
CUSTOM_DISTRIBUTION_HEADER,
|
||||
"Sets min. **plain** level cost for this enchantment to be selected in enchanting table.")
|
||||
"Sets min. **plain** level cost for this enchantment to be selected in enchanting table."
|
||||
)
|
||||
);
|
||||
|
||||
this.setMaxCost(Modifier.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Max_Cost",
|
||||
Modifier.add(costMaxBase, costAdjust, 1),
|
||||
this.setMaxCost(Cost.read(cfg, "Distribution." + DistributionWay.ENCHANTING.getPathName() + ".Cost.Max",
|
||||
new Cost(costStart * costMod, costPerLevel),
|
||||
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",
|
||||
@ -183,6 +181,13 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
"Sets max. **plain** level cost for this enchantment to be selected in enchanting table.")
|
||||
);
|
||||
|
||||
// TODO Check what actually does
|
||||
this.setAnvilCost(ConfigValue.create("Anvil.Cost",
|
||||
Rnd.get(8) + 1,
|
||||
"Sets enchantment anvil cost.",
|
||||
"[*] Works for 1.20.6+ only!"
|
||||
).read(cfg));
|
||||
|
||||
this.distributionOptions.load(cfg);
|
||||
|
||||
|
||||
@ -242,7 +247,7 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
.add(ENCHANTMENT_DESCRIPTION_FORMATTED, () -> String.join("\n", this.getDescriptionFormatted()))
|
||||
.add(ENCHANTMENT_DESCRIPTION_REPLACED, level -> String.join("\n", this.getDescriptionReplaced(level)))
|
||||
.add(ENCHANTMENT_LEVEL, NumberUtil::toRoman)
|
||||
.add(ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(this.getMinLevel()))
|
||||
.add(ENCHANTMENT_LEVEL_MIN, () -> String.valueOf(1))
|
||||
.add(ENCHANTMENT_LEVEL_MAX, () -> String.valueOf(this.getMaxLevel()))
|
||||
.add(ENCHANTMENT_RARITY, () -> plugin.getLangManager().getEnum(this.getRarity()))
|
||||
.add(ENCHANTMENT_FIT_ITEM_TYPES, () -> {
|
||||
@ -327,7 +332,7 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
case ARMOR_FEET -> new EquipmentSlot[]{EquipmentSlot.FEET};
|
||||
case ARMOR, WEARABLE -> new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
case BREAKABLE -> new EquipmentSlot[]{EquipmentSlot.HAND, EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
case VANISHABLE -> EquipmentSlot.values();
|
||||
case VANISHABLE -> EnchantUtils.EQUIPMENT_SLOTS;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + this.getCategory());
|
||||
};
|
||||
}
|
||||
@ -345,10 +350,12 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
|
||||
@Override
|
||||
public boolean checkEnchantLimit(@NotNull ItemStack item) {
|
||||
int limit = Config.CORE_ITEM_ENCHANT_LIMIT.get();
|
||||
int has = EnchantUtils.countCustomEnchantments(item);
|
||||
// Allow to re-enchant item with the same enchantment.
|
||||
if (EnchantUtils.contains(item, this.getEnchantment())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return has < limit;
|
||||
return !EnchantUtils.hasMaximumEnchants(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -373,7 +380,7 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
}
|
||||
|
||||
public int generateLevel() {
|
||||
return Rnd.get(this.getMinLevel(), this.getMaxLevel());
|
||||
return Rnd.get(1, this.getMaxLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -423,12 +430,12 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
|
||||
@Override
|
||||
public int getMinCost(int level) {
|
||||
return this.getMinCost().getIntValue(level);
|
||||
return this.getMinCost().calculate(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCost(int level) {
|
||||
return this.getMaxCost().getIntValue(level);
|
||||
return this.getMaxCost().calculate(level);
|
||||
}
|
||||
|
||||
/*@Override
|
||||
@ -590,16 +597,6 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
this.treasure = treasure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartLevel(int levelMin) {
|
||||
this.minLevel = Math.max(1, levelMin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.minLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxLevel(int levelMax) {
|
||||
this.maxLevel = Math.max(1, levelMax);
|
||||
@ -612,26 +609,36 @@ public abstract class AbstractEnchantmentData extends AbstractFileData<EnchantsP
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Modifier getMinCost() {
|
||||
public Cost getMinCost() {
|
||||
return this.minCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinCost(@NotNull Modifier minCost) {
|
||||
public void setMinCost(@NotNull Cost minCost) {
|
||||
this.minCost = minCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Modifier getMaxCost() {
|
||||
public Cost getMaxCost() {
|
||||
return this.maxCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxCost(@NotNull Modifier maxCost) {
|
||||
public void setMaxCost(@NotNull Cost maxCost) {
|
||||
this.maxCost = maxCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnvilCost() {
|
||||
return anvilCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnvilCost(int anvilCost) {
|
||||
this.anvilCost = anvilCost;
|
||||
}
|
||||
|
||||
/*@Override
|
||||
@NotNull
|
||||
public Modifier getAnvilMergeCost() {
|
||||
|
@ -123,7 +123,7 @@ public class CustomDistribution implements DistributionOptions {
|
||||
int levelCapMin = this.getMinLevel(distributionWay);
|
||||
int levelCapMax = this.getMaxLevel(distributionWay);
|
||||
|
||||
if (levelCapMin <= 0 || levelCapMin < this.enchantmentData.getMinLevel()) levelCapMin = this.enchantmentData.getMinLevel();
|
||||
if (levelCapMin < 1) levelCapMin = 1;
|
||||
if (levelCapMax <= 0 || levelCapMax > this.enchantmentData.getMaxLevel()) levelCapMax = this.enchantmentData.getMaxLevel();
|
||||
|
||||
return Rnd.get(levelCapMin, levelCapMax);
|
||||
@ -132,7 +132,7 @@ public class CustomDistribution implements DistributionOptions {
|
||||
public int getLevelByEnchantCost(int xpLevel) {
|
||||
int get = 0;
|
||||
|
||||
for (int level = this.enchantmentData.getMaxLevel(); level > this.enchantmentData.getMinLevel() - 1; level--) {
|
||||
for (int level = this.enchantmentData.getMaxLevel(); level > 0; level--) {
|
||||
if (xpLevel >= this.enchantmentData.getMinCost(level) && xpLevel <= this.enchantmentData.getMaxCost(level)) {
|
||||
get = level;
|
||||
break;
|
||||
|
@ -62,7 +62,8 @@ public class FlameWalkerEnchant extends AbstractEnchantmentData implements Gener
|
||||
"Sets up to how long (in seconds) blocks will stay before turn back to lava.");
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
@Override
|
||||
public void clear() {
|
||||
BLOCKS_TO_DESTROY.keySet().forEach(location -> location.getBlock().setType(Material.LAVA));
|
||||
BLOCKS_TO_DESTROY.clear();
|
||||
}
|
||||
|
@ -79,6 +79,11 @@ public class TreasureHunterEnchant extends AbstractEnchantmentData implements Ch
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lootTables.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
|
@ -41,7 +41,6 @@ public class SurvivalistEnchant extends AbstractEnchantmentData implements Fishi
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config);
|
||||
|
||||
this.cookingRecipes.clear();
|
||||
this.plugin.getServer().recipeIterator().forEachRemaining(recipe -> {
|
||||
if (recipe instanceof CookingRecipe<?> cookingRecipe && cookingRecipe.getInput().getType().isItem()) {
|
||||
this.cookingRecipes.add(cookingRecipe);
|
||||
@ -49,6 +48,11 @@ public class SurvivalistEnchant extends AbstractEnchantmentData implements Fishi
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.cookingRecipes.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
|
@ -36,6 +36,7 @@ import su.nightexpress.nightcore.util.Plugins;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SilkChestEnchant extends AbstractEnchantmentData implements BlockDropEnchant, SimpeListener {
|
||||
@ -123,9 +124,12 @@ public class SilkChestEnchant extends AbstractEnchantmentData implements BlockDr
|
||||
|
||||
if (!(state instanceof Chest chest)) return false;
|
||||
|
||||
// Добавляем в сундук обратно предметы из дроп листа, кроме самого сундука.
|
||||
event.getItems().removeIf(drop -> drop.getItemStack().getType() == state.getType() && drop.getItemStack().getAmount() == 1);
|
||||
// Remove original chest from drops to prevent duplication.
|
||||
AtomicBoolean originRemoved = new AtomicBoolean(false);
|
||||
event.getItems().removeIf(drop -> drop.getItemStack().getType() == state.getType() && drop.getItemStack().getAmount() == 1 && !originRemoved.getAndSet(true));
|
||||
// Add chest content back to the chest.
|
||||
chest.getBlockInventory().addItem(event.getItems().stream().map(Item::getItemStack).toList().toArray(new ItemStack[0]));
|
||||
// Drop nothing of chest content.
|
||||
event.getItems().clear();
|
||||
|
||||
if (chest.getBlockInventory().isEmpty()) {
|
||||
|
@ -27,6 +27,7 @@ import su.nightexpress.excellentenchants.enchantment.data.ChanceSettingsImpl;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.BukkitThing;
|
||||
import su.nightexpress.nightcore.util.Lists;
|
||||
import su.nightexpress.nightcore.util.LocationUtil;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniParticle;
|
||||
import su.nightexpress.nightcore.util.wrapper.UniSound;
|
||||
@ -44,7 +45,7 @@ public class SmelterEnchant extends AbstractEnchantmentData implements ChanceDat
|
||||
private boolean disableOnCrouch;
|
||||
private ChanceSettingsImpl chanceSettings;
|
||||
|
||||
private final Set<Material> exemptedBlocks;
|
||||
private final Set<Material> exemptedItems;
|
||||
private final Set<FurnaceRecipe> recipes;
|
||||
|
||||
public SmelterEnchant(@NotNull EnchantsPlugin plugin, @NotNull File file) {
|
||||
@ -57,18 +58,12 @@ public class SmelterEnchant extends AbstractEnchantmentData implements ChanceDat
|
||||
Enchantment.SILK_TOUCH.getKey().getKey()
|
||||
);
|
||||
|
||||
this.exemptedBlocks = new HashSet<>();
|
||||
this.exemptedItems = new HashSet<>();
|
||||
this.recipes = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull FileConfig config) {
|
||||
this.plugin.getServer().recipeIterator().forEachRemaining(recipe -> {
|
||||
if (recipe instanceof FurnaceRecipe furnaceRecipe && furnaceRecipe.getInput().getType().isBlock()) {
|
||||
this.recipes.add(furnaceRecipe);
|
||||
}
|
||||
});
|
||||
|
||||
this.chanceSettings = ChanceSettingsImpl.create(config, Modifier.add(10, 8, 1, 100));
|
||||
|
||||
this.disableOnCrouch = ConfigValue.create("Settings.Disable_On_Crouch",
|
||||
@ -82,12 +77,26 @@ public class SmelterEnchant extends AbstractEnchantmentData implements ChanceDat
|
||||
"https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html"
|
||||
).read(config);
|
||||
|
||||
this.exemptedBlocks.addAll(ConfigValue.forSet("Settings.Exempted_Blocks",
|
||||
this.exemptedItems.addAll(ConfigValue.forSet("Settings.Exempted_Blocks",
|
||||
BukkitThing::getMaterial,
|
||||
(cfg, path, set) -> cfg.set(path, set.stream().map(material -> material.getKey().getKey()).toList()),
|
||||
Set.of(Material.STONE),
|
||||
"List of blocks that are immune to smelter effect."
|
||||
(cfg, path, set) -> cfg.set(path, set.stream().map(BukkitThing::toString).toList()),
|
||||
Lists.newSet(Material.COBBLESTONE),
|
||||
"List of blocks / items that are immune to the Smelter effect."
|
||||
).read(config));
|
||||
|
||||
this.plugin.getServer().recipeIterator().forEachRemaining(recipe -> {
|
||||
if (!(recipe instanceof FurnaceRecipe furnaceRecipe)) return;
|
||||
|
||||
if (!this.exemptedItems.contains(furnaceRecipe.getInput().getType())) {
|
||||
this.recipes.add(furnaceRecipe);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.recipes.clear();
|
||||
this.exemptedItems.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -113,8 +122,7 @@ public class SmelterEnchant extends AbstractEnchantmentData implements ChanceDat
|
||||
if (this.disableOnCrouch && entity instanceof Player player && player.isSneaking()) return false;
|
||||
|
||||
BlockState state = event.getBlockState();
|
||||
if (state instanceof Container || this.exemptedBlocks.contains(state.getType())) return false;
|
||||
|
||||
if (state instanceof Container) return false;
|
||||
if (!this.checkTriggerChance(level)) return false;
|
||||
|
||||
List<ItemStack> smelts = new ArrayList<>();
|
||||
@ -122,14 +130,20 @@ public class SmelterEnchant extends AbstractEnchantmentData implements ChanceDat
|
||||
FurnaceRecipe recipe = this.recipes.stream().filter(rec -> rec.getInputChoice().test(drop.getItemStack())).findFirst().orElse(null);
|
||||
if (recipe == null) return false;
|
||||
|
||||
smelts.add(recipe.getResult());
|
||||
// Copy amount of the origin drop item. Fixes Fortune compatibility and overall original drop amount.
|
||||
// Hopefully furnaces will not require multiple input items in the future, otherwise we'll suck here :D
|
||||
int amount = drop.getItemStack().getAmount();
|
||||
ItemStack result = new ItemStack(recipe.getResult());
|
||||
result.setAmount(amount);
|
||||
|
||||
smelts.add(result);
|
||||
return true;
|
||||
});
|
||||
if (smelts.isEmpty()) return false;
|
||||
|
||||
smelts.forEach(itemStack -> this.plugin.populateResource(event, itemStack));
|
||||
|
||||
Block block = event.getBlockState().getBlock();
|
||||
Block block = state.getBlock();
|
||||
if (this.hasVisualEffects()) {
|
||||
Location location = LocationUtil.getCenter(block.getLocation(), true);
|
||||
UniParticle.of(Particle.FLAME).play(location, 0.25, 0.05, 20);
|
||||
|
@ -17,6 +17,7 @@ import su.nightexpress.excellentenchants.enchantment.data.AbstractEnchantmentDat
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.config.ConfigValue;
|
||||
import su.nightexpress.nightcore.config.FileConfig;
|
||||
import su.nightexpress.nightcore.util.Lists;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
@ -76,7 +77,7 @@ public class TunnelEnchant extends AbstractEnchantmentData implements BlockBreak
|
||||
if (block.getDrops(item).isEmpty()) return false;
|
||||
|
||||
|
||||
final List<Block> lastTwoTargetBlocks = player.getLastTwoTargetBlocks(null, 10);
|
||||
final List<Block> lastTwoTargetBlocks = player.getLastTwoTargetBlocks(Lists.newSet(Material.AIR, Material.WATER, Material.LAVA), 10);
|
||||
if (lastTwoTargetBlocks.size() != 2 || !lastTwoTargetBlocks.get(1).getType().isOccluding()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -44,7 +45,7 @@ public class SoulboundEnchant extends AbstractEnchantmentData implements Generic
|
||||
return EnchantmentTarget.BREAKABLE;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onDeath(@NotNull PlayerDeathEvent deathEvent) {
|
||||
Player player = deathEvent.getEntity();
|
||||
if (!this.isAvailableToUse(player)) return;
|
||||
|
@ -106,6 +106,11 @@ public class ScavengerEnchant extends AbstractEnchantmentData implements ChanceD
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lootTables.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChanceSettings getChanceSettings() {
|
||||
|
@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import su.nightexpress.excellentenchants.EnchantsPlugin;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||
import su.nightexpress.excellentenchants.config.Config;
|
||||
import su.nightexpress.excellentenchants.config.Keys;
|
||||
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
|
||||
import su.nightexpress.nightcore.manager.AbstractListener;
|
||||
@ -95,6 +96,10 @@ public class EnchantAnvilListener extends AbstractListener<EnchantsPlugin> {
|
||||
|
||||
private boolean handleCombine(@NotNull PrepareAnvilEvent event, @NotNull ItemStack first, @NotNull ItemStack second, @NotNull ItemStack result) {
|
||||
ItemStack merged = new ItemStack(result.getType().isAir() ? first : result);
|
||||
if (EnchantUtils.countCustomEnchantments(merged) > Config.CORE_ITEM_ENCHANT_LIMIT.get()) {
|
||||
event.setResult(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<EnchantmentData, Integer> chargesMap = new HashMap<>();
|
||||
EnchantUtils.getCustomEnchantments(result).forEach((data, level) -> {
|
||||
|
@ -116,9 +116,20 @@ public class EnchantGenericListener extends AbstractListener<EnchantsPlugin> {
|
||||
ItemStack result = origin.getResult();
|
||||
if (!EnchantUtils.isEnchantable(result)) return;
|
||||
|
||||
int uses = origin.getUses();
|
||||
int maxUses = origin.getMaxUses();
|
||||
boolean expReward = origin.hasExperienceReward();
|
||||
int villagerExperience = origin.getVillagerExperience();
|
||||
float priceMultiplier = origin.getPriceMultiplier();
|
||||
int demand = origin.getDemand();
|
||||
int specialPrice = origin.getSpecialPrice();
|
||||
|
||||
EnchantUtils.updateDisplay(result);
|
||||
|
||||
event.setRecipe(origin);
|
||||
MerchantRecipe recipe = new MerchantRecipe(result, uses, maxUses, expReward, villagerExperience,
|
||||
priceMultiplier, demand, specialPrice);
|
||||
recipe.setIngredients(origin.getIngredients());
|
||||
event.setRecipe(recipe);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
|
@ -116,7 +116,7 @@ public class EnchantPopulationListener extends AbstractListener<EnchantsPlugin>
|
||||
boolean isMythic = Plugins.isLoaded(HookPlugin.MYTHIC_MOBS) && MythicMobsHook.isMythicMob(entity);
|
||||
boolean doPopulation = Config.getDistributionWaySettings(DistributionWay.MOB_EQUIPMENT).isPresent() && !isMythic;
|
||||
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
for (EquipmentSlot slot : EnchantUtils.EQUIPMENT_SLOTS) {
|
||||
ItemStack item = equipment.getItem(slot);
|
||||
if (EnchantUtils.isEnchantable(item)) {
|
||||
if (doPopulation) {
|
||||
|
@ -153,12 +153,9 @@ public class EnchantmentsListMenu extends ConfigMenu<EnchantsPlugin> implements
|
||||
ItemStack currentItem = event.getCurrentItem();
|
||||
if (currentItem == null) return;
|
||||
|
||||
int levelHas = PDCUtil.getInt(currentItem, this.keyLevel).orElse(0);
|
||||
if (levelHas == 0) {
|
||||
levelHas = enchantmentData.getMinLevel();
|
||||
}
|
||||
int levelHas = PDCUtil.getInt(currentItem, this.keyLevel).orElse(1);
|
||||
if (++levelHas > enchantmentData.getMaxLevel()) {
|
||||
levelHas = enchantmentData.getMinLevel();
|
||||
levelHas = 1;
|
||||
}
|
||||
currentItem = this.getEnchantIcon(enchantmentData, levelHas);
|
||||
PDCUtil.set(currentItem, this.keyLevel, levelHas);
|
||||
|
@ -68,7 +68,10 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
|
||||
// Prevent to register enchantments during the runtime.
|
||||
if (this.isLocked) {
|
||||
BY_ID.values().forEach(this::load);
|
||||
getRegistered().forEach(data -> {
|
||||
data.clear();
|
||||
this.load(data);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -165,13 +168,14 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
this.register(RestoreEnchant.ID, file -> new RestoreEnchant(plugin, file));
|
||||
|
||||
this.plugin.getEnchantNMS().freezeRegistry();
|
||||
this.plugin.info("Enchantments Registered: " + EnchantRegistry.getRegistered().size());
|
||||
this.plugin.info("Enchantments Registered: " + BY_ID.size());
|
||||
this.isLocked = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown() {
|
||||
if (!isLocked) {
|
||||
getRegistered().forEach(EnchantmentData::clear);
|
||||
ENCHANTS_MAP.clear();
|
||||
}
|
||||
}
|
||||
@ -231,8 +235,8 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
this.plugin.info("Registered enchantment: " + enchantmentData.getId());
|
||||
}
|
||||
|
||||
private void load(@NotNull EnchantmentData enchant) {
|
||||
enchant.load();
|
||||
private void load(@NotNull EnchantmentData enchantmentData) {
|
||||
enchantmentData.load();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -278,6 +282,6 @@ public class EnchantRegistry extends SimpleManager<EnchantsPlugin> {
|
||||
|
||||
@NotNull
|
||||
public static Collection<EnchantmentData> getRegistered() {
|
||||
return BY_ID.values();
|
||||
return new HashSet<>(BY_ID.values());
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ public class DataGathers {
|
||||
@NotNull
|
||||
@Override
|
||||
public EquipmentSlot[] getEnchantSlots(@NotNull EntityDeathEvent event) {
|
||||
return EquipmentSlot.values();
|
||||
return EnchantUtils.EQUIPMENT_SLOTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -327,7 +327,7 @@ public class DataGathers {
|
||||
@NotNull
|
||||
@Override
|
||||
public EquipmentSlot[] getEnchantSlots(@NotNull EntityResurrectEvent event) {
|
||||
return EquipmentSlot.values();
|
||||
return EnchantUtils.EQUIPMENT_SLOTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,6 +30,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class EnchantUtils {
|
||||
|
||||
public static final EquipmentSlot[] EQUIPMENT_SLOTS = {EquipmentSlot.HAND, EquipmentSlot.OFF_HAND, EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
private static final Map<UUID, EnchantedProjectile> ENCHANTED_PROJECTILE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private static boolean busyBreak = false;
|
||||
@ -241,6 +242,10 @@ public class EnchantUtils {
|
||||
return getLevel(item, enchantment) > 0;
|
||||
}
|
||||
|
||||
public static boolean hasMaximumEnchants(@NotNull ItemStack item) {
|
||||
return countCustomEnchantments(item) >= Config.CORE_ITEM_ENCHANT_LIMIT.get();
|
||||
}
|
||||
|
||||
public static int getLevel(@NotNull ItemStack item, @NotNull Enchantment enchant) {
|
||||
return getEnchantments(item).getOrDefault(enchant, 0);
|
||||
}
|
||||
@ -289,7 +294,7 @@ public class EnchantUtils {
|
||||
|
||||
@NotNull
|
||||
public static Map<EquipmentSlot, ItemStack> getEnchantedEquipment(@NotNull LivingEntity entity) {
|
||||
return getEnchantedEquipment(entity, EquipmentSlot.values());
|
||||
return getEnchantedEquipment(entity, EQUIPMENT_SLOTS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -317,7 +322,7 @@ public class EnchantUtils {
|
||||
@NotNull
|
||||
public static <T extends EnchantmentData> Map<ItemStack, Map<T, Integer>> getEquipped(@NotNull LivingEntity entity,
|
||||
@NotNull Class<T> clazz) {
|
||||
return getEquipped(entity, clazz, EquipmentSlot.values());
|
||||
return getEquipped(entity, clazz, EQUIPMENT_SLOTS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -3,9 +3,7 @@ package su.nightexpress.excellentenchants.hook.impl;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.*;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -29,6 +27,15 @@ public class ProtocolHook {
|
||||
if (isRegistered) return;
|
||||
|
||||
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
|
||||
// Not worked :(
|
||||
manager.addPacketListener(new PacketAdapter(plugin, PacketType.Login.Server.SUCCESS) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
PacketContainer packet = event.getPacket();
|
||||
packet.getBooleans().write(0, false);
|
||||
}
|
||||
});
|
||||
|
||||
manager.addPacketListener(new PacketAdapter(plugin, PacketType.Play.Server.SET_SLOT) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
|
@ -1,13 +1,72 @@
|
||||
# Tranlsated by @qsefthuopq
|
||||
# Last updated:2021-03-15
|
||||
Command:
|
||||
List:
|
||||
Desc: '自定义附魔列表.'
|
||||
Usage: '[player]'
|
||||
DoneOthers: <light_gray>为玩家<light_yellow>%player_name%</light_yellow>打开GUI.</light_gray>
|
||||
GetFuel:
|
||||
Desc: '获得充能物品.'
|
||||
Usage: <enchant> [amount]
|
||||
Done: <light_gray>你获得了<light_yellow>x%amount% %name%</light_yellow>.</light_gray>
|
||||
Enchant:
|
||||
Usage: <附魔名> <等级>
|
||||
Desc: 附魔你手中的物品。
|
||||
Done: '&a附魔成功!'
|
||||
Usage: <enchant> <level> [player] [slot]
|
||||
Desc: '附魔手上的物品.'
|
||||
Done:
|
||||
Self: <light_gray><light_yellow>%item%</light_yellow>的附魔是<light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Others: <light_gray><light_yellow>%player_display_name%</light_yellow>的<light_yellow>%item%</light_yellow>的附魔是<light_yellow>%enchant% %level%</light_yellow>!</light_gray>
|
||||
Error:
|
||||
NoItem: <red>没有要附魔的物品!</red>
|
||||
Book:
|
||||
Usage: <玩家> <附魔名> <等级>
|
||||
Desc: 给予自定义附魔书。
|
||||
Done: 已给予&6%player%&6%enchant%&7附魔书。
|
||||
Usage: <player> <enchant> <level>
|
||||
Desc: '给予自定义附魔书.'
|
||||
Done: <light_gray>将<light_yellow>%enchant%</light_yellow>附魔书给予<light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
RarityBook:
|
||||
Usage: <player> <tier> <level>
|
||||
Desc: '给予指定品质的附魔书'
|
||||
Done: <light_gray>将<light_yellow>%name%</light_yellow>附魔书给予<light_yellow>%player_display_name%</light_yellow>.</light_gray>
|
||||
Error:
|
||||
NoEnchant: '&c没有这种附魔'
|
||||
InvalidEnchantment: <red>无效的参数.</red>
|
||||
InvalidRarity: <red>无效的品质类型!</red>
|
||||
ItemCategory:
|
||||
HELMET: '头盔'
|
||||
CHESTPLATE: '胸甲'
|
||||
LEGGINGS: '护腿'
|
||||
BOOTS: '靴子'
|
||||
ELYTRA: '鞘翅'
|
||||
SWORD: '剑'
|
||||
TRIDENT: '三叉戟'
|
||||
AXE: '斧头'
|
||||
BOW: '弓'
|
||||
CROSSBOW: '弩'
|
||||
HOE: '锄头'
|
||||
PICKAXE: '镐子'
|
||||
SHOVEL: '铲子'
|
||||
FISHING_ROD: '钓鱼竿'
|
||||
SHIELD: '盾牌'
|
||||
TOOL: '工具'
|
||||
EnchantmentTarget:
|
||||
ALL: '全部'
|
||||
ARMOR: '装备'
|
||||
ARMOR_FEET: '靴子'
|
||||
ARMOR_LEGS: '护腿'
|
||||
ARMOR_TORSO: '胸甲'
|
||||
ARMOR_HEAD: '头盔'
|
||||
WEAPON: '武器'
|
||||
TOOL: '工具'
|
||||
BOW: '弓'
|
||||
FISHING_ROD: '钓鱼竿'
|
||||
BREAKABLE: '耐久'
|
||||
WEARABLE: '穿戴'
|
||||
TRIDENT: '三叉戟'
|
||||
CROSSBOW: '弩'
|
||||
VANISHABLE: '隐身'
|
||||
DistributionWay:
|
||||
ENCHANTING: '附魔'
|
||||
VILLAGER: '村民'
|
||||
LOOT_GENERATION: '战利品'
|
||||
FISHING: '钓鱼'
|
||||
MOB_EQUIPMENT: '怪物装备'
|
||||
Rarity:
|
||||
COMMON: '<white>普通</white>'
|
||||
UNCOMMON: '<light_green>勇者</light_green>'
|
||||
RARE: '<purple>史诗</purple>'
|
||||
VERY_RARE: '<red>神话</red>'
|
||||
|
79
MC_1_20_6/pom.xml
Normal file
79
MC_1_20_6/pom.xml
Normal file
@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>MC_1_20_6</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
<classifier>remapped-mojang</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
<id>remap-obf</id>
|
||||
<configuration>
|
||||
<srgIn>org.spigotmc:minecraft-server:1.20.6-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
|
||||
<reverse>true</reverse>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.20.6-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
|
||||
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>remap</goal>
|
||||
</goals>
|
||||
<id>remap-spigot</id>
|
||||
<configuration>
|
||||
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
|
||||
<srgIn>org.spigotmc:minecraft-server:1.20.6-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
|
||||
<remappedDependencies>org.spigotmc:spigot:1.20.6-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,148 @@
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.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.Rarity;
|
||||
import su.nightexpress.excellentenchants.api.enchantment.distribution.VanillaOptions;
|
||||
|
||||
public class CustomEnchantment extends Enchantment {
|
||||
|
||||
private final EnchantmentData enchantmentData;
|
||||
|
||||
private VanillaOptions vanillaOptions;
|
||||
|
||||
@NotNull
|
||||
public static CustomEnchantment from(@NotNull EnchantmentData enchantmentData) {
|
||||
TagKey<Item> category = nmsCategory(enchantmentData);
|
||||
int weight = enchantmentData.getRarity().getWeight();
|
||||
int maxLevel = enchantmentData.getMaxLevel();
|
||||
Cost minCost = new Cost(enchantmentData.getMinCost().base(), enchantmentData.getMinCost().perLevel());
|
||||
Cost maxCost = new Cost(enchantmentData.getMaxCost().base(), enchantmentData.getMaxCost().perLevel());
|
||||
int anvilCost = enchantmentData.getAnvilCost();
|
||||
EquipmentSlot[] slots = nmsSlots(enchantmentData);
|
||||
|
||||
EnchantmentDefinition definition = Enchantment.definition(category, weight, maxLevel, minCost, maxCost, anvilCost, slots);
|
||||
return new CustomEnchantment(enchantmentData, definition);
|
||||
}
|
||||
|
||||
public CustomEnchantment(@NotNull EnchantmentData enchantmentData, @NotNull EnchantmentDefinition definition) {
|
||||
super(definition);
|
||||
this.enchantmentData = enchantmentData;
|
||||
|
||||
if (enchantmentData.getDistributionOptions() instanceof VanillaOptions options) {
|
||||
this.vanillaOptions = options;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkCompatibility(Enchantment other) {
|
||||
ResourceLocation location = BuiltInRegistries.ENCHANTMENT.getKey(other);
|
||||
if (location == null) return false;
|
||||
|
||||
NamespacedKey key = CraftNamespacedKey.fromMinecraft(location);
|
||||
String id = key.getKey();
|
||||
|
||||
// Expensive probably.
|
||||
//org.bukkit.enchantments.Enchantment bukkit = CraftEnchantment.minecraftToBukkit(other);
|
||||
//String id = bukkit.getKey().getKey();
|
||||
|
||||
return !this.enchantmentData.getConflicts().contains(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEnchant(ItemStack item) {
|
||||
if (!super.canEnchant(item)) return false;
|
||||
|
||||
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
|
||||
public boolean isTreasureOnly() {
|
||||
return this.enchantmentData.isTreasure() || this.isCurse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurse() {
|
||||
return this.enchantmentData.isCurse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTradeable() {
|
||||
return this.vanillaOptions != null && this.vanillaOptions.isTradeable();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
public static Rarity nmsRarity(@NotNull EnchantmentData data) {
|
||||
return switch (data.getRarity()) {
|
||||
case RARE -> Rarity.RARE;
|
||||
case COMMON -> Rarity.COMMON;
|
||||
case UNCOMMON -> Rarity.UNCOMMON;
|
||||
case VERY_RARE -> Rarity.VERY_RARE;
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TagKey<Item> nmsCategory(@NotNull EnchantmentData data) {
|
||||
return switch (data.getCategory()) {
|
||||
case WEAPON -> ItemTags.WEAPON_ENCHANTABLE;
|
||||
case TOOL -> ItemTags.MINING_ENCHANTABLE;
|
||||
case ARMOR -> ItemTags.ARMOR_ENCHANTABLE;
|
||||
case BOW -> ItemTags.BOW_ENCHANTABLE;
|
||||
case TRIDENT -> ItemTags.TRIDENT_ENCHANTABLE;
|
||||
case CROSSBOW -> ItemTags.CROSSBOW_ENCHANTABLE;
|
||||
case WEARABLE -> ItemTags.EQUIPPABLE_ENCHANTABLE;
|
||||
case BREAKABLE -> ItemTags.DURABILITY_ENCHANTABLE;
|
||||
case ARMOR_FEET -> ItemTags.FOOT_ARMOR_ENCHANTABLE;
|
||||
case ARMOR_HEAD -> ItemTags.HEAD_ARMOR_ENCHANTABLE;
|
||||
case ARMOR_LEGS -> ItemTags.LEG_ARMOR_ENCHANTABLE;
|
||||
case ARMOR_TORSO -> ItemTags.CHEST_ARMOR_ENCHANTABLE;
|
||||
case VANISHABLE -> ItemTags.VANISHING_ENCHANTABLE;
|
||||
case FISHING_ROD -> ItemTags.FISHING_ENCHANTABLE;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + data.getCategory());
|
||||
};
|
||||
}
|
||||
|
||||
public static EquipmentSlot[] nmsSlots(@NotNull EnchantmentData data) {
|
||||
org.bukkit.inventory.EquipmentSlot[] slots = data.getSlots();
|
||||
EquipmentSlot[] nmsSlots = new EquipmentSlot[slots.length];
|
||||
|
||||
for (int index = 0; index < nmsSlots.length; index++) {
|
||||
org.bukkit.inventory.EquipmentSlot bukkitSlot = slots[index];
|
||||
nmsSlots[index] = CraftEquipmentSlot.getNMS(bukkitSlot);
|
||||
}
|
||||
|
||||
return nmsSlots;
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
package su.nightexpress.excellentenchants;
|
||||
|
||||
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;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlockType;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.enchantments.CraftEnchantment;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftFishHook;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftLivingEntity;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.event.CraftEventFactory;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.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.EquipmentSlot;
|
||||
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.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
public class Internal1_20_6 implements EnchantNMS {
|
||||
|
||||
@Override
|
||||
public void unfreezeRegistry() {
|
||||
Reflex.setFieldValue(BuiltInRegistries.ENCHANTMENT, "l", false); // MappedRegistry#frozen
|
||||
Reflex.setFieldValue(BuiltInRegistries.ENCHANTMENT, "m", new IdentityHashMap<>()); // MappedRegistry#unregisteredIntrusiveHolders
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freezeRegistry() {
|
||||
BuiltInRegistries.ENCHANTMENT.freeze();
|
||||
}
|
||||
|
||||
public void registerEnchantment(@NotNull EnchantmentData data) {
|
||||
CustomEnchantment enchantment = CustomEnchantment.from(data);
|
||||
Registry.register(BuiltInRegistries.ENCHANTMENT, data.getId(), enchantment);
|
||||
|
||||
Enchantment bukkitEnchant = CraftEnchantment.minecraftToBukkit(enchantment);
|
||||
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;
|
||||
ServerPlayer entity = craftPlayer.getHandle();
|
||||
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
|
||||
craftPlayer.getHandle().connection.send(packet);
|
||||
|
||||
player.spigot().sendMessage();
|
||||
}
|
||||
|
||||
/*@NotNull
|
||||
public ItemStack setItemLore(@NotNull ItemStack item, @NotNull List<String> lore) {
|
||||
CraftItemStack craftItem = ensureCraftItemStack(item);
|
||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(craftItem);
|
||||
|
||||
CompoundTag tag = nmsItem.getTag() == null ? new CompoundTag() : nmsItem.getTag();
|
||||
if (!tag.contains(net.minecraft.world.item.ItemStack.TAG_DISPLAY)) {
|
||||
tag.put(net.minecraft.world.item.ItemStack.TAG_DISPLAY, new CompoundTag());
|
||||
}
|
||||
|
||||
CompoundTag displayTag = tag.getCompound(net.minecraft.world.item.ItemStack.TAG_DISPLAY);
|
||||
ListTag loreTag = new ListTag();
|
||||
for (int index = 0; index < lore.size(); index++) {
|
||||
String text = lore.get(index);
|
||||
String json = ComponentSerializer.toString(NightMessage.asComponent(text));
|
||||
loreTag.add(index, StringTag.valueOf(json));
|
||||
}
|
||||
|
||||
displayTag.put(net.minecraft.world.item.ItemStack.TAG_LORE, loreTag);
|
||||
return CraftItemStack.asBukkitCopy(nmsItem);
|
||||
}*/
|
||||
|
||||
@NotNull
|
||||
private static CraftItemStack ensureCraftItemStack(ItemStack item) {
|
||||
return item instanceof CraftItemStack craftItem ? craftItem : CraftItemStack.asCraftCopy(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retrieveHook(@NotNull FishHook hook, @NotNull ItemStack item, @NotNull EquipmentSlot slot) {
|
||||
CraftFishHook craftFishHook = (CraftFishHook) hook;
|
||||
FishingHook handle = craftFishHook.getHandle();
|
||||
|
||||
net.minecraft.world.entity.player.Player owner = handle.getPlayerOwner();
|
||||
if (owner == null) return;
|
||||
|
||||
int result = handle.retrieve(CraftItemStack.asNMSCopy(item));
|
||||
|
||||
net.minecraft.world.entity.EquipmentSlot hand = slot == EquipmentSlot.HAND ? net.minecraft.world.entity.EquipmentSlot.MAINHAND : net.minecraft.world.entity.EquipmentSlot.OFFHAND;
|
||||
|
||||
net.minecraft.world.item.ItemStack itemStack = owner.getItemBySlot(hand);
|
||||
if (itemStack == null) return;
|
||||
|
||||
itemStack.hurtAndBreak(result, handle.getPlayerOwner(), hand);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Material getItemBlockVariant(@NotNull Material material) {
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
if (nmsStack.getItem() instanceof BlockItem blockItem) {
|
||||
return CraftBlockType.minecraftToBukkit(blockItem.getBlock());
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<Block> handleFlameWalker(@NotNull LivingEntity bukkitEntity, @NotNull Location location, int level) {
|
||||
Entity entity = ((CraftLivingEntity) bukkitEntity).getHandle();
|
||||
BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
ServerLevel world = ((CraftWorld) bukkitEntity.getWorld()).getHandle();
|
||||
|
||||
int radius = Math.min(16, 2 + level);
|
||||
BlockState bStone = Blocks.MAGMA_BLOCK.defaultBlockState();
|
||||
BlockPos.MutableBlockPos posAbove = new BlockPos.MutableBlockPos();
|
||||
|
||||
Set<Block> blocks = new HashSet<>();
|
||||
for (BlockPos posNear : BlockPos.betweenClosed(pos.offset(-radius, -1, -radius), pos.offset(radius, -1, radius))) {
|
||||
if (!posNear.closerThan(entity.blockPosition(), radius)) continue;
|
||||
|
||||
posAbove.set(posNear.getX(), posNear.getY() + 1, posNear.getZ());
|
||||
|
||||
BlockState bLavaAbove = world.getBlockState(posAbove);
|
||||
BlockState bLava = world.getBlockState(posNear);
|
||||
|
||||
if (!bLavaAbove.isAir()) continue;
|
||||
if (!bLava.getBlock().equals(Blocks.LAVA)) continue;
|
||||
if (bLava.getValue(LiquidBlock.LEVEL) != 0) continue;
|
||||
if (!bStone.canSurvive(world, posNear)) continue;
|
||||
if (!world.isUnobstructed(bStone, posNear, CollisionContext.empty())) continue;
|
||||
if (!CraftEventFactory.handleBlockFormEvent(world, posNear, bStone, entity)) continue;
|
||||
//world.scheduleTick(posNear, Blocks.STONE, Rnd.get(60, 120));
|
||||
|
||||
Location bukkitLoc = new Location(world.getWorld(), posNear.getX(), posNear.getY(), posNear.getZ());
|
||||
blocks.add(bukkitLoc.getBlock());
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Item popResource(@NotNull Block block, @NotNull ItemStack item) {
|
||||
Level world = ((CraftWorld)block.getWorld()).getHandle();
|
||||
BlockPos pos = ((CraftBlock)block).getPosition();
|
||||
net.minecraft.world.item.ItemStack itemstack = CraftItemStack.asNMSCopy(item);
|
||||
|
||||
float yMod = EntityType.ITEM.getHeight() / 2.0F;
|
||||
double x = (pos.getX() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
|
||||
double y = (pos.getY() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D) - yMod;
|
||||
double z = (pos.getZ() + 0.5F) + Mth.nextDouble(world.random, -0.25D, 0.25D);
|
||||
|
||||
ItemEntity itemEntity = new ItemEntity(world, x, y, z, itemstack);
|
||||
itemEntity.setDefaultPickUpDelay();
|
||||
return (Item) itemEntity.getBukkitEntity();
|
||||
}
|
||||
}
|
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>NMS</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>V1_19_R3</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
@ -30,11 +30,6 @@ public class CustomEnchantment extends Enchantment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.enchantmentData.getMinLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return this.enchantmentData.getMaxLevel();
|
||||
|
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>V1_20_R1</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
@ -30,11 +30,6 @@ public class CustomEnchantment extends Enchantment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.enchantmentData.getMinLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return this.enchantmentData.getMaxLevel();
|
||||
|
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>V1_20_R2</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
@ -30,11 +30,6 @@ public class CustomEnchantment extends Enchantment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.enchantmentData.getMinLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return this.enchantmentData.getMaxLevel();
|
||||
|
@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>V1_20_R3</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -27,12 +27,12 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>API</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>NMS</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>specialsource-maven-plugin</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>2.0.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
@ -30,11 +30,6 @@ public class CustomEnchantment extends Enchantment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinLevel() {
|
||||
return this.enchantmentData.getMinLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return this.enchantmentData.getMaxLevel();
|
||||
|
@ -9,12 +9,14 @@ 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.InteractionHand;
|
||||
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.Items;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentInstance;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
@ -121,13 +123,10 @@ public class V1_20_R3 implements EnchantNMS {
|
||||
ServerPlayer entity = craftPlayer.getHandle();
|
||||
ClientboundAnimatePacket packet = new ClientboundAnimatePacket(entity, id);
|
||||
craftPlayer.getHandle().connection.send(packet);
|
||||
|
||||
player.spigot().sendMessage();
|
||||
}
|
||||
|
||||
/*public ItemStack setItemLore(@NotNull ItemStack item, @NotNull List<String> lore) {
|
||||
lore.add("<translate>enchantment.level.5</translate>");
|
||||
|
||||
/*@NotNull
|
||||
public ItemStack setItemLore(@NotNull ItemStack item, @NotNull List<String> lore) {
|
||||
CraftItemStack craftItem = ensureCraftItemStack(item);
|
||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(craftItem);
|
||||
|
||||
@ -140,24 +139,16 @@ public class V1_20_R3 implements EnchantNMS {
|
||||
ListTag loreTag = new ListTag();
|
||||
for (int index = 0; index < lore.size(); index++) {
|
||||
String text = lore.get(index);
|
||||
System.out.println("text = " + text);
|
||||
String json = ComponentSerializer.toString(NightMessage.create(text).parseIfAbsent());
|
||||
System.out.println("json = " + json);
|
||||
|
||||
Component component = CraftChatMessage.fromJSON(json);
|
||||
System.out.println("component = " + component);
|
||||
String fromComponent = CraftChatMessage.toJSON(component);
|
||||
System.out.println("fromComponent = " + fromComponent);
|
||||
|
||||
|
||||
loreTag.add(index, StringTag.valueOf(fromComponent));
|
||||
String json = ComponentSerializer.toString(NightMessage.asComponent(text));
|
||||
loreTag.add(index, StringTag.valueOf(json));
|
||||
}
|
||||
|
||||
displayTag.put(net.minecraft.world.item.ItemStack.TAG_LORE, loreTag);
|
||||
return CraftItemStack.asBukkitCopy(nmsItem);
|
||||
}*/
|
||||
|
||||
private CraftItemStack ensureCraftItemStack(ItemStack item) {
|
||||
@NotNull
|
||||
private static CraftItemStack ensureCraftItemStack(ItemStack item) {
|
||||
return item instanceof CraftItemStack craftItem ? craftItem : CraftItemStack.asCraftCopy(item);
|
||||
}
|
||||
|
||||
@ -169,16 +160,8 @@ public class V1_20_R3 implements EnchantNMS {
|
||||
net.minecraft.world.entity.player.Player owner = handle.getPlayerOwner();
|
||||
if (owner == null) return;
|
||||
|
||||
int result = handle.retrieve(CraftItemStack.asNMSCopy(item));
|
||||
|
||||
net.minecraft.world.entity.EquipmentSlot hand = slot == EquipmentSlot.HAND ? net.minecraft.world.entity.EquipmentSlot.MAINHAND : net.minecraft.world.entity.EquipmentSlot.OFFHAND;
|
||||
|
||||
net.minecraft.world.item.ItemStack itemStack = owner.getItemBySlot(hand);
|
||||
if (itemStack == null) return;
|
||||
|
||||
itemStack.hurtAndBreak(result, handle.getPlayerOwner(), player -> {
|
||||
player.broadcastBreakEvent(hand);
|
||||
});
|
||||
InteractionHand hand = slot == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND;
|
||||
Items.FISHING_ROD.use(owner.level(), owner, hand);
|
||||
}
|
||||
|
||||
/*@Override
|
||||
|
11
pom.xml
11
pom.xml
@ -7,20 +7,21 @@
|
||||
<groupId>su.nightexpress.excellentenchants</groupId>
|
||||
<artifactId>ExcellentEnchants</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>4.0.4</version>
|
||||
<version>4.0.5</version>
|
||||
<modules>
|
||||
<module>API</module>
|
||||
<module>Core</module>
|
||||
<module>NMS</module>
|
||||
<module>V1_19_R3</module>
|
||||
<module>V1_20_R1</module>
|
||||
<module>V1_20_R2</module>
|
||||
<module>V1_20_R3</module>
|
||||
<module>API</module>
|
||||
<module>MC_1_20_6</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@ -28,7 +29,7 @@
|
||||
<dependency>
|
||||
<groupId>su.nightexpress.nightcore</groupId>
|
||||
<artifactId>nightcore</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<version>2.6.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user