upload
This commit is contained in:
commit
1d508bb581
@ -0,0 +1,83 @@
|
|||||||
|
package su.nightexpress.excellentenchants.api.enchantment;
|
||||||
|
|
||||||
|
import org.bukkit.Keyed;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import su.nexmedia.engine.api.config.JYML;
|
||||||
|
import su.nightexpress.excellentenchants.enchantment.type.ObtainType;
|
||||||
|
import su.nightexpress.excellentenchants.tier.Tier;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface IEnchantment extends Keyed {
|
||||||
|
|
||||||
|
boolean isAvailableToUse(@NotNull LivingEntity entity);
|
||||||
|
|
||||||
|
@NotNull JYML getConfig();
|
||||||
|
|
||||||
|
@NotNull String getId();
|
||||||
|
|
||||||
|
@NotNull String getDisplayName();
|
||||||
|
|
||||||
|
@NotNull String getNameFormatted(int level);
|
||||||
|
|
||||||
|
@NotNull String getNameFormatted(int level, int charges);
|
||||||
|
|
||||||
|
@NotNull List<String> getDescription();
|
||||||
|
|
||||||
|
@NotNull List<String> getDescription(int level);
|
||||||
|
|
||||||
|
@NotNull Set<String> getConflicts();
|
||||||
|
|
||||||
|
@NotNull Tier getTier();
|
||||||
|
|
||||||
|
int getMaxLevel();
|
||||||
|
|
||||||
|
int getStartLevel();
|
||||||
|
|
||||||
|
int getLevelByEnchantCost(int expLevel);
|
||||||
|
|
||||||
|
double getObtainChance(@NotNull ObtainType obtainType);
|
||||||
|
|
||||||
|
int getObtainLevelMin(@NotNull ObtainType obtainType);
|
||||||
|
|
||||||
|
int getObtainLevelMax(@NotNull ObtainType obtainType);
|
||||||
|
|
||||||
|
int generateLevel(@NotNull ObtainType obtainType);
|
||||||
|
|
||||||
|
int getAnvilMergeCost(int level);
|
||||||
|
|
||||||
|
boolean conflictsWith(@NotNull Enchantment enchantment);
|
||||||
|
|
||||||
|
boolean canEnchantItem(@Nullable ItemStack item);
|
||||||
|
|
||||||
|
boolean isCursed();
|
||||||
|
|
||||||
|
boolean isTreasure();
|
||||||
|
|
||||||
|
boolean isChargesEnabled();
|
||||||
|
|
||||||
|
int getChargesMax(int level);
|
||||||
|
|
||||||
|
int getChargesConsumeAmount(int level);
|
||||||
|
|
||||||
|
int getChargesRechargeAmount(int level);
|
||||||
|
|
||||||
|
@NotNull ItemStack getChargesFuel();
|
||||||
|
|
||||||
|
boolean isChargesFuel(@NotNull ItemStack item);
|
||||||
|
|
||||||
|
int getCharges(@NotNull ItemStack item);
|
||||||
|
|
||||||
|
boolean isFullOfCharges(@NotNull ItemStack item);
|
||||||
|
|
||||||
|
boolean isOutOfCharges(@NotNull ItemStack item);
|
||||||
|
|
||||||
|
void consumeCharges(@NotNull ItemStack item, int level);
|
||||||
|
|
||||||
|
void consumeChargesNoUpdate(@NotNull ItemStack item, int level);
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package su.nightexpress.excellentenchants.enchantment.type;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.EnchantmentTarget;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import su.nexmedia.engine.utils.ItemUtil;
|
||||||
|
import su.nightexpress.excellentenchants.config.Config;
|
||||||
|
|
||||||
|
public enum FitItemType {
|
||||||
|
|
||||||
|
HELMET, CHESTPLATE, LEGGINGS, BOOTS, ELYTRA,
|
||||||
|
WEAPON, TOOL, ARMOR, UNIVERSAL,
|
||||||
|
SWORD, TRIDENT, AXE, BOW, CROSSBOW,
|
||||||
|
HOE, PICKAXE, SHOVEL, FISHING_ROD;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static FitItemType getByEnchantmentTarget(@NotNull EnchantmentTarget target) {
|
||||||
|
return switch (target) {
|
||||||
|
case ARMOR -> ARMOR;
|
||||||
|
case ARMOR_FEET -> BOOTS;
|
||||||
|
case ARMOR_LEGS -> LEGGINGS;
|
||||||
|
case ARMOR_TORSO -> CHESTPLATE;
|
||||||
|
case ARMOR_HEAD -> HELMET;
|
||||||
|
case WEAPON -> WEAPON;
|
||||||
|
case TOOL -> TOOL;
|
||||||
|
case BOW -> BOW;
|
||||||
|
case FISHING_ROD -> FISHING_ROD;
|
||||||
|
case TRIDENT -> TRIDENT;
|
||||||
|
case CROSSBOW -> CROSSBOW;
|
||||||
|
case BREAKABLE, WEARABLE -> UNIVERSAL;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIncluded(@NotNull ItemStack item) {
|
||||||
|
return switch (this) {
|
||||||
|
case UNIVERSAL -> ARMOR.isIncluded(item) || WEAPON.isIncluded(item) || TOOL.isIncluded(item) || BOW.isIncluded(item) || FISHING_ROD.isIncluded(item) || ELYTRA.isIncluded(item);
|
||||||
|
case HELMET -> ItemUtil.isHelmet(item);
|
||||||
|
case CHESTPLATE -> ItemUtil.isChestplate(item) || (Config.ENCHANTMENTS_ITEM_CHESTPLATE_ENCHANTS_TO_ELYTRA.get() && ELYTRA.isIncluded(item));
|
||||||
|
case LEGGINGS -> ItemUtil.isLeggings(item);
|
||||||
|
case BOOTS -> ItemUtil.isBoots(item);
|
||||||
|
case ELYTRA -> item.getType() == Material.ELYTRA;
|
||||||
|
case WEAPON -> SWORD.isIncluded(item) || ItemUtil.isTrident(item);
|
||||||
|
case TOOL -> ItemUtil.isTool(item);
|
||||||
|
case ARMOR -> ItemUtil.isArmor(item);
|
||||||
|
case SWORD -> ItemUtil.isSword(item) || (Config.ENCHANTMENTS_ITEM_SWORD_ENCHANTS_TO_AXES.get() && AXE.isIncluded(item));
|
||||||
|
case TRIDENT -> ItemUtil.isTrident(item);
|
||||||
|
case AXE -> ItemUtil.isAxe(item);
|
||||||
|
case BOW -> item.getType() == Material.BOW || (Config.ENCHANTMENTS_ITEM_BOW_ENCHANTS_TO_CROSSBOW.get() && CROSSBOW.isIncluded(item));
|
||||||
|
case CROSSBOW -> item.getType() == Material.CROSSBOW;
|
||||||
|
case HOE -> ItemUtil.isHoe(item);
|
||||||
|
case PICKAXE -> ItemUtil.isPickaxe(item);
|
||||||
|
case SHOVEL -> ItemUtil.isShovel(item);
|
||||||
|
case FISHING_ROD -> item.getType() == Material.FISHING_ROD;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package su.nightexpress.excellentenchants.enchantment.type;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public enum ObtainType {
|
||||||
|
|
||||||
|
ENCHANTING("Enchanting_Table"),
|
||||||
|
VILLAGER("Villagers"),
|
||||||
|
LOOT_GENERATION("Loot_Generation"),
|
||||||
|
FISHING("Fishing"),
|
||||||
|
MOB_SPAWNING("Mob_Spawning");
|
||||||
|
|
||||||
|
private final String pathName;
|
||||||
|
|
||||||
|
ObtainType(@NotNull String pathName) {
|
||||||
|
this.pathName = pathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getPathName() {
|
||||||
|
return pathName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package su.nightexpress.excellentenchants.enchantment.util;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class Evaluator {
|
||||||
|
|
||||||
|
public static double evaluate(@NotNull final String str) {
|
||||||
|
return new Object() {
|
||||||
|
int pos = -1, ch;
|
||||||
|
|
||||||
|
void nextChar() {
|
||||||
|
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean eat(int charToEat) {
|
||||||
|
while (ch == ' ') nextChar();
|
||||||
|
if (ch == charToEat) {
|
||||||
|
nextChar();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double parse() {
|
||||||
|
nextChar();
|
||||||
|
double x = parseExpression();
|
||||||
|
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grammar:
|
||||||
|
// expression = term | expression `+` term | expression `-` term
|
||||||
|
// term = factor | term `*` factor | term `/` factor
|
||||||
|
// factor = `+` factor | `-` factor | `(` expression `)` | number
|
||||||
|
// | functionName `(` expression `)` | functionName factor
|
||||||
|
// | factor `^` factor
|
||||||
|
|
||||||
|
double parseExpression() {
|
||||||
|
double x = parseTerm();
|
||||||
|
for (;;) {
|
||||||
|
if (eat('+')) x += parseTerm(); // addition
|
||||||
|
else if (eat('-')) x -= parseTerm(); // subtraction
|
||||||
|
else return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double parseTerm() {
|
||||||
|
double x = parseFactor();
|
||||||
|
for (;;) {
|
||||||
|
if (eat('*')) x *= parseFactor(); // multiplication
|
||||||
|
else if (eat('/')) x /= parseFactor(); // division
|
||||||
|
else return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double parseFactor() {
|
||||||
|
if (eat('+')) return +parseFactor(); // unary plus
|
||||||
|
if (eat('-')) return -parseFactor(); // unary minus
|
||||||
|
|
||||||
|
double x;
|
||||||
|
int startPos = this.pos;
|
||||||
|
if (eat('(')) { // parentheses
|
||||||
|
x = parseExpression();
|
||||||
|
if (!eat(')')) throw new RuntimeException("Missing ')'");
|
||||||
|
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
|
||||||
|
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
|
||||||
|
x = Double.parseDouble(str.substring(startPos, this.pos));
|
||||||
|
} else if (ch >= 'a' && ch <= 'z') { // functions
|
||||||
|
while (ch >= 'a' && ch <= 'z') nextChar();
|
||||||
|
String func = str.substring(startPos, this.pos);
|
||||||
|
if (eat('(')) {
|
||||||
|
x = parseExpression();
|
||||||
|
if (!eat(')')) throw new RuntimeException("Missing ')' after argument to " + func);
|
||||||
|
} else {
|
||||||
|
x = parseFactor();
|
||||||
|
}
|
||||||
|
x = switch (func) {
|
||||||
|
case "sqrt" -> Math.sqrt(x);
|
||||||
|
case "sin" -> Math.sin(Math.toRadians(x));
|
||||||
|
case "cos" -> Math.cos(Math.toRadians(x));
|
||||||
|
case "tan" -> Math.tan(Math.toRadians(x));
|
||||||
|
default -> throw new RuntimeException("Unknown function: " + func);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected: " + (char)ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}.parse();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package su.nightexpress.excellentenchants.nms;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
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.item.SpawnEggItem;
|
||||||
|
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.block.Block;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock;
|
||||||
|
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.CraftItemStack;
|
||||||
|
import org.bukkit.entity.FishHook;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class V1_20_R2 implements EnchantNMS {
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retrieveHook(@NotNull FishHook hook, @NotNull ItemStack item) {
|
||||||
|
CraftFishHook craftFishHook = (CraftFishHook) hook;
|
||||||
|
FishingHook handle = craftFishHook.getHandle();
|
||||||
|
handle.retrieve(CraftItemStack.asNMSCopy(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ItemStack getSpawnEgg(@NotNull LivingEntity entity) {
|
||||||
|
CraftLivingEntity craftLivingEntity = (CraftLivingEntity) entity;
|
||||||
|
net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle();
|
||||||
|
|
||||||
|
SpawnEggItem eggItem = SpawnEggItem.byId(livingEntity.getType());
|
||||||
|
if (eggItem == null) return null;
|
||||||
|
|
||||||
|
return CraftItemStack.asBukkitCopy(eggItem.getDefaultInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user