- 204
- 7
- 25
Захотелось увеличть дальность работы дронам в мсхели. Перекопал всё что можно в моде, вот небольшая хронология:
- Теперь можно полноценно летатьгдето в еб**ях очень далеко и возвращаться, но летаем мы в полной пустоте без чанков. И вот тут я пришёл в тупик, несколько дней уже пытаюсь как то использовать ванильные пакеты чанков, но успеха нет.
Выглядит это вот так -

Прошу помощи у гениев моддинга. Как передвавать и рисовать дальние чанки? Может всё что я сделал говно полное и моежет предложить более правильный и простой вариант реализации?
Спасибо.
- Убрал "обрыв связи"(хз как назвать) при достижении n-дистанции от игрока. Теперь можно улететь чуть дальше.
- Следующая беда. Когда энтити дрона пропадает на клиенте, то и связь с упарвелнием тоже. Перехватываю пакет деспавна, проверяю кого именно деспавним и отменяю его обработку.
перехват 1:
@SubscribeEvent
public void onClientConnect(FMLNetworkEvent.ClientConnectedToServerEvent event) {
ChannelPipeline pipeline = event.manager.channel().pipeline();
pipeline.addBefore("packet_handler", "custom_packet_handler", new W_PacketHandler());
}
class W_PacketHandler extends SimpleChannelInboundHandler<Packet> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
if (msg instanceof S13PacketDestroyEntities) {
S13PacketDestroyEntities packet = (S13PacketDestroyEntities) msg;
int[] entityIds = packet.func_149098_c();
List<Integer> newEntityIds = new ArrayList<>();
for (int entityId : entityIds) {
Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(entityId);
if(Minecraft.getMinecraft().thePlayer.ridingEntity != null) {
if (entity != null && entity instanceof MCH_EntityAircraft && ((MCH_EntityAircraft) entity).getAcInfo().isUAV) {
if(Minecraft.getMinecraft().thePlayer.ridingEntity instanceof MCH_EntityUavStation){
MCH_EntityUavStation uavStation = (MCH_EntityUavStation) Minecraft.getMinecraft().thePlayer.ridingEntity;
if(uavStation.getControlAircract()!=null){
if(entity.getEntityId() == uavStation.getControlAircract().getEntityId()){
newEntityIds.add(entityId);
}
}
}
}
}
}
if (!newEntityIds.isEmpty()) {
int[] remainingIds = Arrays.stream(entityIds)
.filter(id -> !newEntityIds.contains(id))
.toArray();
if (remainingIds.length > 0) {
S13PacketDestroyEntities newPacket = new S13PacketDestroyEntities(remainingIds);
ctx.fireChannelRead(newPacket);
return;
} else {
return;
}
}
}
ctx.fireChannelRead(msg);
}
- Добавил постоянную загрузку чанков вокруг дрона на стороне сервера, что бы мог летать там где нет игроков. Работает! Теперь можно летать в пустоте и даже вернуться, правда для клиента дрон зависает на границе "непрогруза энетити", но....
- Но когда дрон возвращается в зону прогрузки для игрока, то он как бы "переспавнивается"(entityID остаётся тотже, но сам обьект существа заменяется новым), добавил аналогичный перехват пакета со "спавном", теперь когда дрон взовращается в "зону прогрузки энтити", то всё как бы норм, снова видны все измение в полёте и т.д.
- Начал изучать как игра передаёт клиенту инфу о существах. Пришёл почти к полному копипасту метода sendLocationToAllClients из класса EntityTrackerEntry. Код выполнял в методе обновления станции управления(MCH_EntityUavStation)
onUpdate_Server в MCH_EntityUavStation:
private void onUpdate_Server() {
//ориг код
if(super.riddenByEntity != null) {
if(super.riddenByEntity.isDead) {
//ориг код
} else {
if(getControlAircract()!=null){ //мой код обновления
MCH_EntityAircraft cac = getControlAircract();
if(super.riddenByEntity instanceof EntityPlayerMP){
((EntityPlayerMP) super.riddenByEntity).addChatMessage(new ChatComponentText("Дистанция до дрона -> "+cac.getDistanceToEntity(this)));
int i = cac.myEntitySize.multiplyBy32AndRound(cac.posX);
int j = MathHelper.floor_double(cac.posY * 32.0D);
int k = cac.myEntitySize.multiplyBy32AndRound(cac.posZ);
int l = MathHelper.floor_float(cac.rotationYaw * 256.0F / 360.0F);
int i1 = MathHelper.floor_float(cac.rotationPitch * 256.0F / 360.0F);
int j1 = i - this.lastScaledXPosition;
int k1 = j - this.lastScaledYPosition;
int l1 = k - this.lastScaledZPosition;
Object object = null;
boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || cac.ticksExisted % 60 == 0;
boolean flag1 = Math.abs(l - this.lastYaw) >= 4 || Math.abs(i1 - this.lastPitch) >= 4;
if (this.ticksExisted > 0) {
if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128) {
if (flag && flag1) {
object = new S14PacketEntity.S17PacketEntityLookMove(cac.getEntityId(), (byte)j1, (byte)k1, (byte)l1, (byte)l, (byte)i1);
} else if (flag) {
object = new S14PacketEntity.S15PacketEntityRelMove(cac.getEntityId(), (byte)j1, (byte)k1, (byte)l1);
} else if (flag1) {
object = new S14PacketEntity.S16PacketEntityLook(cac.getEntityId(), (byte)l, (byte)i1);
}
} else {
object = new S18PacketEntityTeleport(cac.getEntityId(), i, j, k, (byte)l, (byte)i1);
}
}
if (false) {
double d0 = cac.motionX - this.motionX;
double d1 = cac.motionY - this.motionY;
double d2 = cac.motionZ - this.motionZ;
double d3 = 0.02D;
double d4 = d0 * d0 + d1 * d1 + d2 * d2;
if (d4 > d3 * d3 || d4 > 0.0D && cac.motionX == 0.0D && cac.motionY == 0.0D && cac.motionZ == 0.0D) {
this.motionX = cac.motionX;
this.motionY = cac.motionY;
this.motionZ = cac.motionZ;
((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(cac.getEntityId(), this.motionX, this.motionY, this.motionZ));
}
}
if (object != null) {
((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket((Packet)object);
}
// this.sendMetadataToAllAssociatedPlayers();
DataWatcher datawatcher = cac.getDataWatcher();
if (datawatcher.hasChanges()) {
((EntityPlayerMP)this.riddenByEntity).playerNetServerHandler.sendPacket(new S1CPacketEntityMetadata(cac.getEntityId(), datawatcher, false));
}
if (flag) {
this.lastScaledXPosition = i;
this.lastScaledYPosition = j;
this.lastScaledZPosition = k;
}
if (flag1) {
this.lastYaw = l;
this.lastPitch = i1;
}
}
}
}
}
//ориг код
}
- Теперь можно полноценно летать
Выглядит это вот так -

Прошу помощи у гениев моддинга. Как передвавать и рисовать дальние чанки? Может всё что я сделал говно полное и моежет предложить более правильный и простой вариант реализации?
Спасибо.