9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 01:49:30 +00:00

Merge pull request #175 from jhqwqmc/dev

feat(bukkit): 别样的投射三叉戟实现
This commit is contained in:
XiaoMoMi
2025-05-13 21:04:33 +08:00
committed by GitHub
7 changed files with 688 additions and 10 deletions

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.bukkit.entity.projectile;
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
import io.papermc.paper.event.player.PlayerStopUsingItemEvent;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.scheduler.impl.FoliaTask;
@@ -9,22 +11,22 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.entity.projectile.CustomProjectile;
import net.momirealms.craftengine.core.entity.projectile.ProjectileManager;
import net.momirealms.craftengine.core.entity.projectile.ProjectileMeta;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Bukkit;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.ThrowableProjectile;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.world.EntitiesLoadEvent;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@@ -95,6 +97,48 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
});
}
@EventHandler
public void onPlayerInteract(PlayerItemConsumeEvent event) {
ItemStack item = event.getItem();
String type = getType(item);
if (type == null) return;
if (type.equals("bow") || type.equals("spear")) {
event.setCancelled(true);
}
}
@EventHandler
public void onPlayerStopUsingItem(PlayerStopUsingItemEvent event) {
ItemStack item = event.getItem();
String type = getType(item);
if (type == null) return;
int ticksHeldFor = event.getTicksHeldFor();
Player player = event.getPlayer();
if (type.equals("bow")) {
if (ticksHeldFor < 3) return;
// player.sendMessage("可以投出自定义弓: " + item.getType() + " 持续 " + ticksHeldFor + " 刻");
} else if (type.equals("trident")) {
if (ticksHeldFor < 10) return;
// player.sendMessage("可以投出自定义三叉戟: " + item.getType() + " 持续 " + ticksHeldFor + " 刻");
Object nmsItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(item);
Object nmsServerLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld());
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(player);
boolean success = TridentRelease.releaseUsing(nmsItemStack, nmsServerLevel, nmsEntity);
// player.sendMessage("释放成功: " + success);
}
}
@Nullable
private String getType(ItemStack item) {
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(item);
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
if (optionalCustomItem.isEmpty()) return null;
CustomItem<ItemStack> customItem = optionalCustomItem.get();
ProjectileMeta meta = customItem.settings().projectileMeta();
if (meta == null) return null;
return meta.type();
}
public class ProjectileInjectTask implements Runnable {
private final Projectile projectile;
private final SchedulerTask task;

View File

@@ -0,0 +1,515 @@
package net.momirealms.craftengine.bukkit.entity.projectile;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
public class TridentRelease {
private TridentRelease() {}
public static boolean releaseUsing(Object stack, Object level, Object entity) {
if (VersionHelper.isOrAbove1_21_2()) {
return releaseUsing_1_21_2(stack, level, entity);
} else if (VersionHelper.isOrAbove1_21()) {
return releaseUsing_1_21(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20_5()) {
return releaseUsing_1_20_5(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20_3()) {
return releaseUsing_1_20_3(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20()) {
return releaseUsing_1_20(stack, level, entity);
}
return false;
}
private static boolean releaseUsing_1_21_2(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
Object copyStack1 = FastNMS.INSTANCE.method$ItemStack$copy(stack);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack1)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack1, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
if (spinStrength == 0.0F) {
Object projectile = FastNMS.INSTANCE.method$Projectile$ThrownTrident$spawnProjectileFromRotationDelayed(
level,
copyStack,
entity,
0.0F,
2.5F,
1.0F
);
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile))
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$Projectile$Delayed$attemptSpawn(projectile)) {
FastNMS.INSTANCE.method$AbstractContainerMenu$sendAllDataToRemote(FastNMS.INSTANCE.field$Player$containerMenu(entity));
return false;
}
Object trident = FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile);
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtWithoutBreaking(stack, 1, entity);
FastNMS.INSTANCE.method$ItemStack$consume(stack, 1, entity);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(trident, copyStack1);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(trident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
trident,
FastNMS.INSTANCE.method$Holder$value(sound),
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
FastNMS.INSTANCE.method$Holder$value(sound),
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_21(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
FastNMS.INSTANCE.method$Holder$value(sound),
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
FastNMS.INSTANCE.method$Holder$value(sound),
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20_5(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
Reflections.instance$SoundEvent$TRIDENT_THROW,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
} else {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20_3(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
Reflections.instance$SoundEvent$TRIDENT_THROW,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
} else {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$ThrownTrident$tridentItem(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
Reflections.instance$SoundEvent$TRIDENT_THROW,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
} else {
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
Reflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
}

View File

@@ -3368,11 +3368,23 @@ public class Reflections {
);
public static final Object instance$SoundEvent$EMPTY;
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_1;
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_2;
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_3;
public static final Object instance$SoundEvent$TRIDENT_THROW;
static {
try {
Object key = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "intentionally_empty");
instance$SoundEvent$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, key);
Object intentionallyEmpty = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "intentionally_empty");
instance$SoundEvent$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, intentionallyEmpty);
Object tridentRiptide1 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident_riptide_1");
instance$SoundEvent$TRIDENT_RIPTIDE_1 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide1);
Object tridentRiptide2 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident_riptide_2");
instance$SoundEvent$TRIDENT_RIPTIDE_2 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide2);
Object tridentRiptide3 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident.riptide_3");
instance$SoundEvent$TRIDENT_RIPTIDE_3 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide3);
Object tridentThrow = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident.throw");
instance$SoundEvent$TRIDENT_THROW = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentThrow);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
@@ -6669,7 +6681,7 @@ public class Reflections {
);
public static final Constructor<?> constructor$ClientboundCustomPayloadPacket = requireNonNull(
ReflectionUtils.getTheOnlyConstructor(clazz$ClientboundCustomPayloadPacket)
ReflectionUtils.getConstructor(clazz$ClientboundCustomPayloadPacket, 0)
);
// 1.20.2+
@@ -6684,4 +6696,100 @@ public class Reflections {
public static final Field field$PaperPluginClassLoader$libraryLoader = Optional.ofNullable(clazz$PaperPluginClassLoader)
.map(it -> ReflectionUtils.getDeclaredField(it, URLClassLoader.class, 0))
.orElse(null);
public static final Method method$SoundSource$values = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$SoundSource, clazz$SoundSource.arrayType()
)
);
public static final Object instance$SoundSource$MASTER;
public static final Object instance$SoundSource$MUSIC;
public static final Object instance$SoundSource$RECORDS;
public static final Object instance$SoundSource$WEATHER;
public static final Object instance$SoundSource$BLOCKS;
public static final Object instance$SoundSource$HOSTILE;
public static final Object instance$SoundSource$NEUTRAL;
public static final Object instance$SoundSource$PLAYERS;
public static final Object instance$SoundSource$AMBIENT;
public static final Object instance$SoundSource$VOICE;
static {
try {
Object[] values = (Object[]) method$SoundSource$values.invoke(null);
instance$SoundSource$MASTER = values[0];
instance$SoundSource$MUSIC = values[1];
instance$SoundSource$RECORDS = values[2];
instance$SoundSource$WEATHER = values[3];
instance$SoundSource$BLOCKS = values[4];
instance$SoundSource$HOSTILE = values[5];
instance$SoundSource$NEUTRAL = values[6];
instance$SoundSource$PLAYERS = values[7];
instance$SoundSource$AMBIENT = values[8];
instance$SoundSource$VOICE = values[9];
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
public static final Class<?> clazz$MoverType = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.entity.EnumMoveType",
"world.entity.MoverType"
)
);
public static final Method method$MoverType$values = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$MoverType, clazz$MoverType.arrayType()
)
);
public static final Object instance$MoverType$SELF;
public static final Object instance$MoverType$PLAYER;
public static final Object instance$MoverType$PISTON;
public static final Object instance$MoverType$SHULKER_BOX;
public static final Object instance$MoverType$SHULKER;
static {
try {
Object[] values = (Object[]) method$MoverType$values.invoke(null);
instance$MoverType$SELF = values[0];
instance$MoverType$PLAYER = values[1];
instance$MoverType$PISTON = values[2];
instance$MoverType$SHULKER_BOX = values[3];
instance$MoverType$SHULKER = values[4];
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
public static final Class<?> clazz$AbstractArrow$Pickup = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.entity.projectile.EntityArrow$PickupStatus",
"world.entity.projectile.AbstractArrow$Pickup"
)
);
public static final Method method$AbstractArrow$Pickup$values = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$AbstractArrow$Pickup, clazz$AbstractArrow$Pickup.arrayType()
)
);
public static final Object instance$AbstractArrow$Pickup$DISALLOWED;
public static final Object instance$AbstractArrow$Pickup$ALLOWED;
public static final Object instance$AbstractArrow$Pickup$CREATIVE_ONLY;
static {
try {
Object[] values = (Object[]) method$AbstractArrow$Pickup$values.invoke(null);
instance$AbstractArrow$Pickup$DISALLOWED = values[0];
instance$AbstractArrow$Pickup$ALLOWED = values[1];
instance$AbstractArrow$Pickup$CREATIVE_ONLY = values[2];
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
}

View File

@@ -5,5 +5,5 @@ import net.momirealms.craftengine.core.util.Key;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public record ProjectileMeta(Key item, ItemDisplayContext displayType, Vector3f scale, Vector3f translation, Quaternionf rotation) {
public record ProjectileMeta(Key item, ItemDisplayContext displayType, Vector3f scale, Vector3f translation, Quaternionf rotation, String type) {
}

View File

@@ -226,7 +226,8 @@ public class ItemSettings {
Vector3f translation = MiscUtils.getAsVector3f(args.getOrDefault("translation", "0"), "translation");
Vector3f scale = MiscUtils.getAsVector3f(args.getOrDefault("scale", "1"), "scale");
Quaternionf rotation = MiscUtils.getAsQuaternionf(ResourceConfigUtils.get(args, "rotation-left", "rotation"), "rotation-left");
return settings -> settings.projectileMeta(new ProjectileMeta(customTridentItemId, displayType, scale, translation, rotation));
String type = args.getOrDefault("type", "none").toString();
return settings -> settings.projectileMeta(new ProjectileMeta(customTridentItemId, displayType, scale, translation, rotation, type));
}));
registerFactory("dyeable", (value -> {
boolean bool = (boolean) value;

View File

@@ -12,6 +12,8 @@ public class MCUtils {
private MCUtils() {}
public static final float DEG_TO_RAD = ((float)Math.PI / 180F);
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
private static final float[] SIN = make(new float[65536], (sineTable) -> {
for(int i = 0; i < sineTable.length; ++i) {
@@ -231,6 +233,14 @@ public class MCUtils {
return SIN[(int) (value * 10430.378F) & '\uffff'];
}
public static float cos(float value) {
return SIN[(int)(value * 10430.378F + 16384.0F) & '\uffff'];
}
public static float sqrt(float value) {
return (float)Math.sqrt(value);
}
public static <T> T findNextInIterable(Iterable<T> iterable, @Nullable T object) {
Iterator<T> iterator = iterable.iterator();
T next = iterator.next();

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3
snake_yaml_version=2.4
anti_grief_version=0.15
nms_helper_version=0.65.21
nms_helper_version=0.65.23
evalex_version=3.5.0
reactive_streams_version=1.0.4
amazon_awssdk_version=2.31.23