优化炮弹区块加载
This commit is contained in:
parent
c5f87bb215
commit
c75246dbfc
3 changed files with 64 additions and 40 deletions
|
@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.AnimatedEntity;
|
import com.atsuishio.superbwarfare.entity.AnimatedEntity;
|
||||||
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.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;
|
||||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||||
|
@ -25,7 +26,6 @@ import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
|
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.Explosion;
|
import net.minecraft.world.level.Explosion;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
@ -35,7 +35,6 @@ import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.EntityHitResult;
|
import net.minecraft.world.phys.EntityHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.common.world.ForgeChunkManager;
|
|
||||||
import net.minecraftforge.network.NetworkHooks;
|
import net.minecraftforge.network.NetworkHooks;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
import net.minecraftforge.network.PlayMessages;
|
import net.minecraftforge.network.PlayMessages;
|
||||||
|
@ -272,21 +271,8 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt
|
||||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo,
|
ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo,
|
||||||
1, 0, 0, 0, 0.001, true);
|
1, 0, 0, 0, 0.001, true);
|
||||||
|
|
||||||
var movement = this.getDeltaMovement();
|
// 更新需要加载的区块
|
||||||
var currentX = this.chunkPosition().x;
|
ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks);
|
||||||
var currentZ = this.chunkPosition().z;
|
|
||||||
var nextX = movement.x > 0 ? currentX + 1 : currentX - 1;
|
|
||||||
var nextZ = movement.z > 0 ? currentZ + 1 : currentZ - 1;
|
|
||||||
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, currentZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, nextZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, currentZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, nextZ, true, false);
|
|
||||||
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(currentX, currentZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(currentX, nextZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(nextX, currentZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(nextX, nextZ));
|
|
||||||
}
|
}
|
||||||
if (this.tickCount > 600 || this.isInWater()) {
|
if (this.tickCount > 600 || this.isInWater()) {
|
||||||
if (this.level() instanceof ServerLevel) {
|
if (this.level() instanceof ServerLevel) {
|
||||||
|
@ -404,9 +390,7 @@ public class CannonShellEntity extends ThrowableItemProjectile implements GeoEnt
|
||||||
@Override
|
@Override
|
||||||
public void onRemovedFromWorld() {
|
public void onRemovedFromWorld() {
|
||||||
if (this.level() instanceof ServerLevel serverLevel) {
|
if (this.level() instanceof ServerLevel serverLevel) {
|
||||||
for (long chunkPos : this.loadedChunks) {
|
ChunkLoadTool.unloadAllChunks(serverLevel, this, this.loadedChunks);
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos), false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.onRemovedFromWorld();
|
super.onRemovedFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.atsuishio.superbwarfare.entity.projectile;
|
package com.atsuishio.superbwarfare.entity.projectile;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.ModUtils;
|
|
||||||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||||
import com.atsuishio.superbwarfare.init.ModEntities;
|
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
|
import com.atsuishio.superbwarfare.tools.ChunkLoadTool;
|
||||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -25,7 +25,6 @@ import net.minecraft.world.level.block.BellBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.EntityHitResult;
|
import net.minecraft.world.phys.EntityHitResult;
|
||||||
import net.minecraftforge.common.world.ForgeChunkManager;
|
|
||||||
import net.minecraftforge.network.NetworkHooks;
|
import net.minecraftforge.network.NetworkHooks;
|
||||||
import net.minecraftforge.network.PlayMessages;
|
import net.minecraftforge.network.PlayMessages;
|
||||||
import software.bernie.geckolib.animatable.GeoEntity;
|
import software.bernie.geckolib.animatable.GeoEntity;
|
||||||
|
@ -158,21 +157,8 @@ public class MortarShellEntity extends ThrowableItemProjectile implements GeoEnt
|
||||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo,
|
ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo,
|
||||||
1, 0, 0, 0, 0.001, true);
|
1, 0, 0, 0, 0.001, true);
|
||||||
|
|
||||||
var movement = this.getDeltaMovement();
|
// 更新需要加载的区块
|
||||||
var currentX = this.chunkPosition().x;
|
ChunkLoadTool.updateLoadedChunks(serverLevel, this, this.loadedChunks);
|
||||||
var currentZ = this.chunkPosition().z;
|
|
||||||
var nextX = movement.x > 0 ? currentX + 1 : currentX - 1;
|
|
||||||
var nextZ = movement.z > 0 ? currentZ + 1 : currentZ - 1;
|
|
||||||
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, currentZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, currentX, nextZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, currentZ, true, false);
|
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, nextX, nextZ, true, false);
|
|
||||||
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(currentX, currentZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(currentX, nextZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(nextX, currentZ));
|
|
||||||
this.loadedChunks.add(ChunkPos.asLong(nextX, nextZ));
|
|
||||||
}
|
}
|
||||||
if (this.tickCount > this.life || this.isInWater()) {
|
if (this.tickCount > this.life || this.isInWater()) {
|
||||||
if (this.level() instanceof ServerLevel) {
|
if (this.level() instanceof ServerLevel) {
|
||||||
|
@ -199,9 +185,7 @@ public class MortarShellEntity extends ThrowableItemProjectile implements GeoEnt
|
||||||
@Override
|
@Override
|
||||||
public void onRemovedFromWorld() {
|
public void onRemovedFromWorld() {
|
||||||
if (this.level() instanceof ServerLevel serverLevel) {
|
if (this.level() instanceof ServerLevel serverLevel) {
|
||||||
for (long chunkPos : this.loadedChunks) {
|
ChunkLoadTool.unloadAllChunks(serverLevel, this, this.loadedChunks);
|
||||||
ForgeChunkManager.forceChunk(serverLevel, ModUtils.MODID, this, ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos), false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.onRemovedFromWorld();
|
super.onRemovedFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.atsuishio.superbwarfare.tools;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.ModUtils;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraftforge.common.world.ForgeChunkManager;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ChunkLoadTool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据动量计算需要加载的区块并卸载不再需要加载的区块
|
||||||
|
*/
|
||||||
|
public static void updateLoadedChunks(ServerLevel level, Entity entity, Set<Long> loadedChunks) {
|
||||||
|
var x = entity.position().x;
|
||||||
|
var z = entity.position().z;
|
||||||
|
var nextX = x + entity.getDeltaMovement().x;
|
||||||
|
var nextZ = z + entity.getDeltaMovement().z;
|
||||||
|
|
||||||
|
// 加载当前区块和下一tick会进入的区块
|
||||||
|
var newChunks = new HashSet<Long>();
|
||||||
|
newChunks.add(ChunkPos.asLong(new BlockPos((int) x, 0, (int) z)));
|
||||||
|
newChunks.add(ChunkPos.asLong(new BlockPos((int) nextX, 0, (int) nextZ)));
|
||||||
|
|
||||||
|
// 计算需要更新的区块
|
||||||
|
var chunksToLoad = newChunks.stream().filter(chunk -> !loadedChunks.contains(chunk)).toList();
|
||||||
|
var chunksToUnload = loadedChunks.stream().filter(chunk -> !newChunks.contains(chunk)).toList();
|
||||||
|
|
||||||
|
chunksToLoad.forEach(chunk -> {
|
||||||
|
var chunkPos = new ChunkPos(chunk);
|
||||||
|
ForgeChunkManager.forceChunk(level, ModUtils.MODID, entity, chunkPos.x, chunkPos.z, true, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
chunksToUnload.forEach(chunk -> {
|
||||||
|
var chunkPos = new ChunkPos(chunk);
|
||||||
|
ForgeChunkManager.forceChunk(level, ModUtils.MODID, entity, chunkPos.x, chunkPos.z, false, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
loadedChunks.clear();
|
||||||
|
loadedChunks.addAll(newChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卸载所有已加载区块
|
||||||
|
*/
|
||||||
|
public static void unloadAllChunks(ServerLevel level, Entity entity, Set<Long> loadedChunks) {
|
||||||
|
loadedChunks.forEach(chunk -> {
|
||||||
|
var chunkPos = new ChunkPos(chunk);
|
||||||
|
ForgeChunkManager.forceChunk(level, ModUtils.MODID, entity, chunkPos.x, chunkPos.z, false, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue