修复一个可能导致崩溃的问题

This commit is contained in:
17146 2024-06-03 16:20:31 +08:00
parent df3514e758
commit baa4e216cd
4 changed files with 19 additions and 54 deletions

View file

@ -1,21 +0,0 @@
package net.mcreator.target.api.entity;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.EntityHitResult;
//from TACZ
/**
* 用于进行一些并非 {@link LivingEntity} 但是可被子弹击中的特殊实体的处理
*/
public interface ITargetEntity {
/**
* @param projectile 弹射物实体
* @param result 击中实体的位置
* @param source 伤害源类型
* @param damage 伤害值
*/
void onProjectileHit(Entity projectile, EntityHitResult result, DamageSource source, float damage);
}

View file

@ -1,10 +1,6 @@
package net.mcreator.target.entity; package net.mcreator.target.entity;
import net.mcreator.target.TargetMod; import net.mcreator.target.TargetMod;
import net.mcreator.target.api.entity.ITargetEntity;
import net.mcreator.target.tools.HitboxHelper;
import net.mcreator.target.headshot.BoundingBoxManager;
import net.mcreator.target.headshot.IHeadshotBox;
import net.mcreator.target.init.TargetModDamageTypes; import net.mcreator.target.init.TargetModDamageTypes;
import net.mcreator.target.init.TargetModEntities; import net.mcreator.target.init.TargetModEntities;
import net.mcreator.target.init.TargetModParticleTypes; import net.mcreator.target.init.TargetModParticleTypes;
@ -12,6 +8,7 @@ import net.mcreator.target.init.TargetModSounds;
import net.mcreator.target.network.message.ClientIndicatorMessage; import net.mcreator.target.network.message.ClientIndicatorMessage;
import net.mcreator.target.network.message.PlayerGunKillMessage; import net.mcreator.target.network.message.PlayerGunKillMessage;
import net.mcreator.target.tools.ExtendedEntityRayTraceResult; import net.mcreator.target.tools.ExtendedEntityRayTraceResult;
import net.mcreator.target.tools.HitboxHelper;
import net.mcreator.target.tools.ParticleTool; import net.mcreator.target.tools.ParticleTool;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -21,7 +18,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundSoundPacket; import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
@ -42,12 +38,10 @@ import net.minecraftforge.entity.IEntityAdditionalSpawnData;
import net.minecraftforge.entity.PartEntity; import net.minecraftforge.entity.PartEntity;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages; import net.minecraftforge.network.PlayMessages;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -115,6 +109,9 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa
if (result == null) continue; if (result == null) continue;
Vec3 hitPos = result.getHitPos(); Vec3 hitPos = result.getHitPos();
if (hitPos == null) continue;
double distanceToHit = startVec.distanceTo(hitPos); double distanceToHit = startVec.distanceTo(hitPos);
if (distanceToHit < closestDistance) { if (distanceToHit < closestDistance) {
hitVec = hitPos; hitVec = hitPos;
@ -146,23 +143,24 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa
return hitEntities; return hitEntities;
} }
/**
* From TaC-Z
*/
@Nullable @Nullable
@SuppressWarnings("unchecked")
private EntityResult getHitResult(Entity entity, Vec3 startVec, Vec3 endVec) { private EntityResult getHitResult(Entity entity, Vec3 startVec, Vec3 endVec) {
double expandHeight = entity instanceof Player && !entity.isCrouching() ? 0.0625 : 0.0; double expandHeight = entity instanceof Player && !entity.isCrouching() ? 0.0625 : 0.0;
AABB boundingBox = entity.getBoundingBox(); AABB boundingBox = entity.getBoundingBox();
Vec3 velocity = new Vec3(entity.getX() - entity.xOld, entity.getY() - entity.yOld, entity.getZ() - entity.zOld); Vec3 velocity = new Vec3(entity.getX() - entity.xOld, entity.getY() - entity.yOld, entity.getZ() - entity.zOld);
// hitbox 延迟补偿只有射击者是玩家且被击中者也是玩家才进行此类延迟补偿计算
if (entity instanceof ServerPlayer player && this.shooter instanceof ServerPlayer serverPlayerOwner) { if (entity instanceof ServerPlayer player && this.shooter instanceof ServerPlayer serverPlayerOwner) {
int ping = Mth.floor((serverPlayerOwner.latency / 1000.0) * 20.0 + 0.5); int ping = Mth.floor((serverPlayerOwner.latency / 1000.0) * 20.0 + 0.5);
boundingBox = HitboxHelper.getBoundingBox(player, ping); boundingBox = HitboxHelper.getBoundingBox(player, ping);
velocity = HitboxHelper.getVelocity(player, ping); velocity = HitboxHelper.getVelocity(player, ping);
} }
// 应用蹲伏导致的 hitbox 变形
boundingBox = boundingBox.expandTowards(0, expandHeight, 0); boundingBox = boundingBox.expandTowards(0, expandHeight, 0);
// 根据速度一定程度地扩展 hitbox
boundingBox = boundingBox.expandTowards(velocity.x, velocity.y, velocity.z); boundingBox = boundingBox.expandTowards(velocity.x, velocity.y, velocity.z);
// 玩家 hitbox 修正可以通过 Config 调整
double playerHitboxOffset = 3; double playerHitboxOffset = 3;
if (entity instanceof ServerPlayer) { if (entity instanceof ServerPlayer) {
if (entity.getVehicle() != null) { if (entity.getVehicle() != null) {
@ -170,16 +168,13 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa
} }
boundingBox = boundingBox.move(velocity.multiply(playerHitboxOffset, playerHitboxOffset, playerHitboxOffset)); boundingBox = boundingBox.move(velocity.multiply(playerHitboxOffset, playerHitboxOffset, playerHitboxOffset));
} }
// 给所有实体统一应用的 Hitbox 偏移其数值为实验得出的定值
if (entity.getVehicle() != null || entity instanceof ITargetEntity) { if (entity.getVehicle() != null) {
boundingBox = boundingBox.move(velocity.multiply(-2.5, -2.5, -2.5)); boundingBox = boundingBox.move(velocity.multiply(-2.5, -2.5, -2.5));
} }
boundingBox = boundingBox.move(velocity.multiply(-5, -5, -5)); boundingBox = boundingBox.move(velocity.multiply(-5, -5, -5));
// 计算射线与实体 boundingBox 的交点
Vec3 hitPos = boundingBox.clip(startVec, endVec).orElse(null); Vec3 hitPos = boundingBox.clip(startVec, endVec).orElse(null);
/* Check for headshot */
if (hitPos == null) { if (hitPos == null) {
return null; return null;
} }
@ -244,9 +239,9 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa
this.setPosRaw(this.getX() + vec.x, this.getY() + vec.y, this.getZ() + vec.z); this.setPosRaw(this.getX() + vec.x, this.getY() + vec.y, this.getZ() + vec.z);
} }
Vec3 vecp = this.getDeltaMovement(); Vec3 movement = this.getDeltaMovement();
this.setDeltaMovement(vecp.x, vecp.y - 0.1, vecp.z); this.setDeltaMovement(movement.x, movement.y - 0.1, movement.z);
this.tickCount++; this.tickCount++;
if (this.tickCount > 30) { if (this.tickCount > 30) {

View file

@ -90,9 +90,6 @@ public class TargetModVariables {
clone.bowPullHold = original.bowPullHold; clone.bowPullHold = original.bowPullHold;
clone.bowPull = original.bowPull; clone.bowPull = original.bowPull;
clone.playerDoubleJump = original.playerDoubleJump; clone.playerDoubleJump = original.playerDoubleJump;
// clone.hitIndicator = original.hitIndicator;
// clone.headIndicator = original.headIndicator;
// clone.killIndicator = original.killIndicator;
if (event.getEntity().level().isClientSide()) return; if (event.getEntity().level().isClientSide()) return;
@ -305,9 +302,7 @@ public class TargetModVariables {
nbt.putBoolean("bow_pull_hold", bowPullHold); nbt.putBoolean("bow_pull_hold", bowPullHold);
nbt.putBoolean("bow_pull", bowPull); nbt.putBoolean("bow_pull", bowPull);
nbt.putBoolean("player_double_jump", playerDoubleJump); nbt.putBoolean("player_double_jump", playerDoubleJump);
// nbt.putInt("hit_indicator", hitIndicator);
// nbt.putInt("head_indicator", headIndicator);
// nbt.putInt("kill_indicator", killIndicator);
return nbt; return nbt;
} }
@ -327,9 +322,6 @@ public class TargetModVariables {
bowPullHold = nbt.getBoolean("bow_pull_hold"); bowPullHold = nbt.getBoolean("bow_pull_hold");
bowPull = nbt.getBoolean("bow_pull"); bowPull = nbt.getBoolean("bow_pull");
playerDoubleJump = nbt.getBoolean("player_double_jump"); playerDoubleJump = nbt.getBoolean("player_double_jump");
// hitIndicator = nbt.getInt("hit_indicator");
// headIndicator = nbt.getInt("head_indicator");
// killIndicator = nbt.getInt("kill_indicator");
} }
} }
@ -386,9 +378,6 @@ public class TargetModVariables {
variables.bowPullHold = message.data.bowPullHold; variables.bowPullHold = message.data.bowPullHold;
variables.bowPull = message.data.bowPull; variables.bowPull = message.data.bowPull;
variables.playerDoubleJump = message.data.playerDoubleJump; variables.playerDoubleJump = message.data.playerDoubleJump;
// variables.hitIndicator = message.data.hitIndicator;
// variables.headIndicator = message.data.headIndicator;
// variables.killIndicator = message.data.killIndicator;
}); });
} }
} }

View file

@ -8,7 +8,9 @@ import net.minecraft.world.phys.Vec3;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.WeakHashMap; import java.util.WeakHashMap;
//from TACZ /**
* From TAC-Z
*/
public final class HitboxHelper { public final class HitboxHelper {
// 玩家位置缓存表 // 玩家位置缓存表
private static final WeakHashMap<Player, LinkedList<Vec3>> PLAYER_POSITION = new WeakHashMap<>(); private static final WeakHashMap<Player, LinkedList<Vec3>> PLAYER_POSITION = new WeakHashMap<>();
@ -17,7 +19,7 @@ public final class HitboxHelper {
// 玩家速度缓存表 // 玩家速度缓存表
private static final WeakHashMap<Player, LinkedList<Vec3>> PLAYER_VELOCITY = new WeakHashMap<>(); private static final WeakHashMap<Player, LinkedList<Vec3>> PLAYER_VELOCITY = new WeakHashMap<>();
// 命中箱缓存 Tick 上限 // 命中箱缓存 Tick 上限
private static final int SAVE_TICK = Mth.floor(1000 / 1000 * 20 + 0.5); private static final int SAVE_TICK = Mth.floor(20 + 0.5);
public static void onPlayerTick(Player player) { public static void onPlayerTick(Player player) {
if (player.isSpectator()) { if (player.isSpectator()) {