尝试自行实现客户端实体动量同步
This commit is contained in:
parent
e35c7ff530
commit
867f7a6bde
9 changed files with 89 additions and 82 deletions
|
@ -178,6 +178,7 @@ public class ModUtils {
|
||||||
addNetworkMessage(SwitchVehicleWeaponMessage.class, SwitchVehicleWeaponMessage::encode, SwitchVehicleWeaponMessage::decode, SwitchVehicleWeaponMessage::handler);
|
addNetworkMessage(SwitchVehicleWeaponMessage.class, SwitchVehicleWeaponMessage::encode, SwitchVehicleWeaponMessage::decode, SwitchVehicleWeaponMessage::handler);
|
||||||
addNetworkMessage(RadarSetTargetMessage.class, RadarSetTargetMessage::encode, RadarSetTargetMessage::decode, RadarSetTargetMessage::handler);
|
addNetworkMessage(RadarSetTargetMessage.class, RadarSetTargetMessage::encode, RadarSetTargetMessage::decode, RadarSetTargetMessage::handler);
|
||||||
addNetworkMessage(ChangeVehicleSeatMessage.class, ChangeVehicleSeatMessage::encode, ChangeVehicleSeatMessage::decode, ChangeVehicleSeatMessage::handler);
|
addNetworkMessage(ChangeVehicleSeatMessage.class, ChangeVehicleSeatMessage::encode, ChangeVehicleSeatMessage::decode, ChangeVehicleSeatMessage::handler);
|
||||||
|
addNetworkMessage(ClientMotionSyncMessage.class, ClientMotionSyncMessage::encode, ClientMotionSyncMessage::decode, ClientMotionSyncMessage::handler, Optional.of(NetworkDirection.PLAY_TO_CLIENT));
|
||||||
|
|
||||||
event.enqueueWork(() -> BrewingRecipeRegistry.addRecipe(Ingredient.of(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)),
|
event.enqueueWork(() -> BrewingRecipeRegistry.addRecipe(Ingredient.of(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)),
|
||||||
Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get())));
|
Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get())));
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.init.*;
|
import com.atsuishio.superbwarfare.init.*;
|
||||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||||
|
import com.atsuishio.superbwarfare.network.message.ClientMotionSyncMessage;
|
||||||
import com.atsuishio.superbwarfare.tools.ChunkLoadTool;
|
import com.atsuishio.superbwarfare.tools.ChunkLoadTool;
|
||||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||||
|
@ -50,7 +51,7 @@ import software.bernie.geckolib.util.GeckoLibUtil;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class CannonShellEntity extends ThrowableItemProjectile implements GeoEntity {
|
public class CannonShellEntity extends ThrowableItemProjectile implements GeoEntity, FastProjectile {
|
||||||
|
|
||||||
public static final EntityDataAccessor<String> ANIMATION = SynchedEntityData.defineId(CannonShellEntity.class, EntityDataSerializers.STRING);
|
public static final EntityDataAccessor<String> ANIMATION = SynchedEntityData.defineId(CannonShellEntity.class, EntityDataSerializers.STRING);
|
||||||
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
||||||
|
@ -255,6 +256,15 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt
|
||||||
}
|
}
|
||||||
this.discard();
|
this.discard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.syncMotion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncMotion() {
|
||||||
|
if (!this.level().isClientSide) {
|
||||||
|
ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new ClientMotionSyncMessage(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void causeExplode(Entity entity) {
|
private void causeExplode(Entity entity) {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
package com.atsuishio.superbwarfare.entity.projectile;
|
package com.atsuishio.superbwarfare.entity.projectile;
|
||||||
|
|
||||||
public interface FastProjectile {
|
public interface FastProjectile {
|
||||||
|
|
||||||
|
void syncMotion();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.init.*;
|
import com.atsuishio.superbwarfare.init.*;
|
||||||
import com.atsuishio.superbwarfare.item.Transcript;
|
import com.atsuishio.superbwarfare.item.Transcript;
|
||||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||||
|
import com.atsuishio.superbwarfare.network.message.ClientMotionSyncMessage;
|
||||||
import com.atsuishio.superbwarfare.network.message.PlayerGunKillMessage;
|
import com.atsuishio.superbwarfare.network.message.PlayerGunKillMessage;
|
||||||
import com.atsuishio.superbwarfare.tools.*;
|
import com.atsuishio.superbwarfare.tools.*;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -300,6 +301,15 @@ public class ProjectileEntity extends Projectile implements IEntityAdditionalSpa
|
||||||
Math.max(this.getDeltaMovement().length() - 1.1 * this.tickCount, 0.2), true
|
Math.max(this.getDeltaMovement().length() - 1.1 * this.tickCount, 0.2), true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.syncMotion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncMotion() {
|
||||||
|
if (!this.level().isClientSide) {
|
||||||
|
ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new ClientMotionSyncMessage(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -55,9 +55,9 @@ public class ModEntities {
|
||||||
public static final RegistryObject<EntityType<MortarShellEntity>> MORTAR_SHELL = register("projectile_mortar_shell",
|
public static final RegistryObject<EntityType<MortarShellEntity>> MORTAR_SHELL = register("projectile_mortar_shell",
|
||||||
EntityType.Builder.<MortarShellEntity>of(MortarShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(MortarShellEntity::new).sized(0.5f, 0.5f));
|
EntityType.Builder.<MortarShellEntity>of(MortarShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(MortarShellEntity::new).sized(0.5f, 0.5f));
|
||||||
public static final RegistryObject<EntityType<ProjectileEntity>> PROJECTILE = register("projectile",
|
public static final RegistryObject<EntityType<ProjectileEntity>> PROJECTILE = register("projectile",
|
||||||
EntityType.Builder.<ProjectileEntity>of(ProjectileEntity::new, MobCategory.MISC).setCustomClientFactory(ProjectileEntity::new).setTrackingRange(64).noSave().noSummon().sized(0.25f, 0.25f));
|
EntityType.Builder.<ProjectileEntity>of(ProjectileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setCustomClientFactory(ProjectileEntity::new).setTrackingRange(64).noSave().noSummon().sized(0.25f, 0.25f));
|
||||||
public static final RegistryObject<EntityType<CannonShellEntity>> CANNON_SHELL = register("projectile_cannon_shell",
|
public static final RegistryObject<EntityType<CannonShellEntity>> CANNON_SHELL = register("projectile_cannon_shell",
|
||||||
EntityType.Builder.<CannonShellEntity>of(CannonShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(CannonShellEntity::new).sized(0.5f, 0.5f));
|
EntityType.Builder.<CannonShellEntity>of(CannonShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(CannonShellEntity::new).sized(0.5f, 0.5f));
|
||||||
public static final RegistryObject<EntityType<HandGrenadeEntity>> HAND_GRENADE_ENTITY = register("projectile_hand_grenade_entity",
|
public static final RegistryObject<EntityType<HandGrenadeEntity>> HAND_GRENADE_ENTITY = register("projectile_hand_grenade_entity",
|
||||||
EntityType.Builder.<HandGrenadeEntity>of(HandGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(HandGrenadeEntity::new).sized(0.3f, 0.3f));
|
EntityType.Builder.<HandGrenadeEntity>of(HandGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(HandGrenadeEntity::new).sized(0.3f, 0.3f));
|
||||||
public static final RegistryObject<EntityType<RgoGrenadeEntity>> RGO_GRENADE = register("projectile_rgo_grenade",
|
public static final RegistryObject<EntityType<RgoGrenadeEntity>> RGO_GRENADE = register("projectile_rgo_grenade",
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
package com.atsuishio.superbwarfare.mixins;
|
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From Fast Projectile Fix
|
|
||||||
* <br>
|
|
||||||
* Author: Roki27
|
|
||||||
*/
|
|
||||||
@Mixin(ClientboundSetEntityMotionPacket.class)
|
|
||||||
public class ClientboundSetEntityMotionPacketMixin {
|
|
||||||
|
|
||||||
@Mutable
|
|
||||||
@Final
|
|
||||||
@Shadow
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
@Mutable
|
|
||||||
@Final
|
|
||||||
@Shadow
|
|
||||||
private int xa;
|
|
||||||
|
|
||||||
@Mutable
|
|
||||||
@Final
|
|
||||||
@Shadow
|
|
||||||
private int ya;
|
|
||||||
|
|
||||||
@Mutable
|
|
||||||
@Final
|
|
||||||
@Shadow
|
|
||||||
private int za;
|
|
||||||
|
|
||||||
// TODO 实现仅对 FastProjectile 对象的动量修改
|
|
||||||
@Inject(method = "<init>(ILnet/minecraft/world/phys/Vec3;)V", at = @At(value = "RETURN"))
|
|
||||||
public void init(int entityId, Vec3 motion, CallbackInfo ci) {
|
|
||||||
this.xa = (int) (motion.x * 8000.0D);
|
|
||||||
this.ya = (int) (motion.y * 8000.0D);
|
|
||||||
this.za = (int) (motion.z * 8000.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "<init>(Lnet/minecraft/network/FriendlyByteBuf;)V",
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/network/FriendlyByteBuf;readShort()S"))
|
|
||||||
public short readShort(FriendlyByteBuf instance) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At(value = "RETURN"), cancellable = true)
|
|
||||||
public void read(FriendlyByteBuf buf, CallbackInfo ci) {
|
|
||||||
ci.cancel();
|
|
||||||
this.xa = buf.readInt();
|
|
||||||
this.ya = buf.readInt();
|
|
||||||
this.za = buf.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "Lnet/minecraft/network/protocol/game/ClientboundSetEntityMotionPacket;" +
|
|
||||||
"write(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At(value = "HEAD"), cancellable = true)
|
|
||||||
public void write(FriendlyByteBuf buf, CallbackInfo ci) {
|
|
||||||
ci.cancel();
|
|
||||||
buf.writeVarInt(this.id);
|
|
||||||
buf.writeInt(this.xa);
|
|
||||||
buf.writeInt(this.ya);
|
|
||||||
buf.writeInt(this.za);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,10 +7,7 @@ import com.atsuishio.superbwarfare.config.client.KillMessageConfig;
|
||||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||||
import com.atsuishio.superbwarfare.event.KillMessageHandler;
|
import com.atsuishio.superbwarfare.event.KillMessageHandler;
|
||||||
import com.atsuishio.superbwarfare.menu.EnergyMenu;
|
import com.atsuishio.superbwarfare.menu.EnergyMenu;
|
||||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
import com.atsuishio.superbwarfare.network.message.*;
|
||||||
import com.atsuishio.superbwarfare.network.message.ContainerDataMessage;
|
|
||||||
import com.atsuishio.superbwarfare.network.message.GunsDataMessage;
|
|
||||||
import com.atsuishio.superbwarfare.network.message.RadarMenuOpenMessage;
|
|
||||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||||
import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
|
import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
|
||||||
import net.minecraft.client.CameraType;
|
import net.minecraft.client.CameraType;
|
||||||
|
@ -88,4 +85,15 @@ public class ClientPacketHandler {
|
||||||
Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON));
|
Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void handleClientSyncMotion(ClientMotionSyncMessage message, Supplier<NetworkEvent.Context> ctx) {
|
||||||
|
if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||||
|
var level = Minecraft.getInstance().level;
|
||||||
|
if (level == null) return;
|
||||||
|
Entity entity = level.getEntity(message.id);
|
||||||
|
if (entity != null) {
|
||||||
|
entity.lerpMotion(message.x, message.y, message.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.atsuishio.superbwarfare.network.message;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.network.ClientPacketHandler;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ClientMotionSyncMessage {
|
||||||
|
|
||||||
|
public final int id;
|
||||||
|
public final double x;
|
||||||
|
public final double y;
|
||||||
|
public final double z;
|
||||||
|
|
||||||
|
public ClientMotionSyncMessage(Entity entity) {
|
||||||
|
this(entity.getId(), entity.getDeltaMovement());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientMotionSyncMessage(int id, Vec3 motion) {
|
||||||
|
this.id = id;
|
||||||
|
this.x = motion.x;
|
||||||
|
this.y = motion.y;
|
||||||
|
this.z = motion.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encode(ClientMotionSyncMessage message, FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeVarInt(message.id);
|
||||||
|
buffer.writeDouble(message.x);
|
||||||
|
buffer.writeDouble(message.y);
|
||||||
|
buffer.writeDouble(message.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientMotionSyncMessage decode(FriendlyByteBuf buffer) {
|
||||||
|
int id = buffer.readVarInt();
|
||||||
|
double x = buffer.readDouble();
|
||||||
|
double y = buffer.readDouble();
|
||||||
|
double z = buffer.readDouble();
|
||||||
|
return new ClientMotionSyncMessage(id, new Vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handler(ClientMotionSyncMessage message, Supplier<NetworkEvent.Context> ctx) {
|
||||||
|
ctx.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||||
|
() -> () -> ClientPacketHandler.handleClientSyncMotion(message, ctx)));
|
||||||
|
ctx.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"refmap": "mixins.superbwarfare.refmap.json",
|
"refmap": "mixins.superbwarfare.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"ClientboundSetEntityMotionPacketMixin",
|
|
||||||
"ClientboundSetPassengersPacketMixin",
|
"ClientboundSetPassengersPacketMixin",
|
||||||
"ExplosionMixin",
|
"ExplosionMixin",
|
||||||
"LivingEntityMixin",
|
"LivingEntityMixin",
|
||||||
|
|
Loading…
Add table
Reference in a new issue